﻿/// <reference path="../jquery-1.4.4.js" />
/// <reference path="../jquery-1.4.4-vsdoc.js" />

/*!  
** Copyright (c) 2011 Ray Liang (http://www.dotnetage.com)
** Dual licensed under the MIT and GPL licenses:
** http://www.opensource.org/licenses/mit-license.php
** http://www.gnu.org/licenses/gpl.html
** 
**----------------------------------------------------------------
** title        : DJME 2
** version   : 2.0.3
** modified: 2011-4-5
**----------------------------------------------------------------
*/

(function ($) {
    $.widget("ui.buttonex", {
        options: {
            type: "standard",
            clientClick: null,
            oncommand: null,
            cmd: null,
            stateChanged: null,
            downClass: null,
            hoverClass: null,
            imageUrl: null,
            downImage: null,
            hoverImage: null,
            isbg: false,
            linkUrl: null,
            primaryIconImage: null,
            primaryIcon: null,
            secondaryIcon: null,
            secondaryIconImage: null,
            states: null,
            group: null,
            radio: false,
            value: null,
            target: "_self",
            splitButton: false,
            spliterClick: null,
            containment: 'parent'
        },
        _create: function () {
            var opts = this.options, self = this, eventPrefix = this.widgetEventPrefix, el = this.element;

            if (this.options.stateChanged)
                this.element.bind(eventPrefix + "stateChanged", this.options.stateChanged);
            if ((this.options.splitButton) && (opts.spliterClick))
                el.bind(eventPrefix + "spliterClick", opts.spliterClick);

            if (this.options.oncommand)
                el.bind(eventPrefix + "oncommand", this.options.oncommand);

            this.element.bind("mouseenter", function () { el.addClass("d-button-hover"); })
                               .bind("mouseleave", function () { el.removeClass("d-button-hover"); })
                               .bind("mousedown", function () { el.addClass("d-button-down"); })
                               .bind("mouseup", function () { el.removeClass("d-button-down"); });

            this.element.bind("click", function (event) {
                event.stopPropagation();
                if (opts.states) {
                    self._nextState();
                    self._setState();
                    self._triggerEvent("stateChanged", self.curstate.value);
                }

                if ((opts.type == "standard") && (opts.clientClick == null) && (opts.linkUrl)) location = opts.linkUrl;

                if (opts.splitButton) {
                    if (opts.cmd)
                        self._triggerEvent("oncommand", opts.cmd);
                    else
                        self._triggerEvent("spliterClick");
                }

                self._triggerEvent("clientClick");
            });

            if (opts.group) el.addClass(opts.group);

            if (opts.states)
                this._initState();

            this["_" + opts.type]();

            if (opts.states)
                this._setState();

            if (opts.clientClick)
                this.element.bind(eventPrefix + "clientClick", opts.clientClick);

            this.element.attr("tabIndex", 1).disableSelection();

        },
        _setOption: function (key, value) {
            var self = this;
            if (key == "value") {
                if (this.options.states) {
                    $.each(self.options.states, function (i, state) {
                        if (state.value == value) {
                            self.stateIndex = i;
                            $.extend(self.curstate, self.options.states[self.stateIndex]);
                            return false;
                        }
                    });
                    self._setState();
                }
            }
            else
                self.options[key] = value;
        },
        _setState: function () {
            var state = this.curstate, el = this.element, self = this;
            if (state) {
                if (state.text) {
                    var $txt = $(".d-button-text", el);
                    if ($txt.length) $txt.text(state.text);
                }

                var $value = $(".d-button-value", el);
                if ($value.length) {
                    if ((state.value != undefined) && (state.value != NaN) && (state.value != null))
                        $value.val(state.value);
                    else
                        $value.val("");
                }

                this.options.value = state.value;

                if (this.curclass)
                    this.element.removeClass(this.curclass);

                if (state.cssclass) {
                    this.curclass = state.cssclass;
                    this.element.addClass(state.cssclass);
                }

                if (state.imageUrl) {
                    if (this.options.isbg) {
                        var $link = $(">.d-button-link", el);
                        if ($link.length) { $link.css({ "background-image": "url(" + state.imageUrl + ");" }); } else {
                            var $imgbg = $(".d-button-img", el);
                            $imgbg.css({ "background-image": "url(" + state.imageUrl + ");" });
                        }
                    } else {
                        var $img = $(".d-button-img", el);
                        $img.attr("src", state.imageUrl);
                    }
                }

                var $pimg = $(".d-button-primary-icon", el),
                 $simg = $(".d-button-secondary-icon", el);

                if ($pimg.length) {
                    if (state.primaryIconImage) $pimg.attr("src", state.primaryIconImage);
                    else {
                        if (state.primaryIcon) {
                            $pimg.removeClass()
                                      .addClass("d-button-primary-icon")
                                      .addClass(state.primaryIcon);
                        }
                    }
                }

                if ($simg.length) {
                    if (state.secondaryIconImage) {
                        if (state.secondaryIconImage) $simg.attr("src", state.secondaryIconImage);
                    } else {
                        if (state.secondaryIcon) {
                            $simg.removeClass()
                                      .addClass("d-button-secondary-icon")
                                      .addClass(state.secondaryIconImage);
                        }
                    }
                }
            }

            if (this.options.radio) {
                if (this.options.value) {
                    var $groupElements = el.siblings(".d-radio");
                    if (this.options.group) {
                        if (this.options.containment == "parent")
                            $groupElements = el.siblings("." + this.options.group);
                        else
                            $groupElements = $("." + this.options.group, $(this.options.containment)); //.remove(el);
                    }

                    $groupElements.each(function (i, ge) {
                        if ($(ge).context != el.context) {
                            if ($(ge).hasClass("d-radio")) {
                                $(ge).buttonex("option", "value", false);
                            }
                            else {
                                if ((self.options.group) && $(ge).hasClass(self.options.group)) {
                                    $(ge).buttonex("option", "value", false);
                                }
                            }
                        }
                    });
                }
            }
        },
        _nextState: function () {
            this.stateIndex++;
            if (this.stateIndex >= this.options.states.length)
                this.stateIndex = 0;
            //if (this.curstate.cssclass) this.curclass = this.curstate.cssclass;
            $.extend(this.curstate, this.options.states[this.stateIndex]);
        },
        _initState: function () {
            var curState = {}, opts = this.options, self = this;

            if (this.options.states && this.options.states.length) {
                this.stateIndex = 0;

                if (this.element.text()) {
                    this.element.wrapInner($("<span/>").addClass("d-button-text"));
                    var $t = $(".d-button-text", this.element);
                    if ($t.children().length > 0) $t.children().appendTo(this.element);
                }

                $.each(this.options.states, function (i, state) {
                    if (state.selected) {
                        $.extend(curState, state);
                        self.stateIndex = i;
                        return false;
                    }
                });

                if (self.stateIndex == 0) { $.extend(curState, this.options.states[0]); }
            }
            else {
                curState = {
                    imageUrl: opts.imageUrl,
                    primaryIconImage: opts.primaryIconImage,
                    primaryIcon: opts.primaryIcon,
                    secondaryIcon: opts.secondaryIcon,
                    secondaryIconImage: opts.secondaryIconImage
                };
            }
            this.curstate = curState;
        },
        _createSpliter: function () {
            var self = this, el = this.element,
            $wrapper = $("<table/>").attr("cellspacing", "0")
            .attr("cellPadding", "0")
            .addClass("d-button-wrapper"),
            $tr = $("<tr/>").appendTo($wrapper),
            $wrapperL = $("<td/>").addClass("d-wrapper-l")
            .attr("valign", "middle")
            .appendTo($tr),
            $wrapperR = $("<td/>").addClass("d-split-button")
            .attr("valign", "middle")
            .appendTo($tr);

            self.element.after($wrapper);
            self.element.appendTo($wrapperL);

            $("<span/>").addClass("d-split-icon")
                                .appendTo($wrapperR);

            $wrapperR.click(function (event) {
                event.stopPropagation();
                self._triggerEvent("spliterClick", self);
            })
                            .bind("mouseenter", function () { el.addClass("d-button-hover"); })
                            .bind("mouseleave", function () { el.removeClass("d-button-hover"); })
                            .bind("mousedown", function () { el.addClass("d-button-down"); })
                            .bind("mouseup", function () { el.removeClass("d-button-down"); });

        },
        _createIcons: function (element) {
            var opts = this.options;

            if (opts.primaryIconImage) {
                $("<img alt=''/>").addClass("d-button-primary-icon")
                                            .attr("src", opts.primaryIconImage)
                                             .css({ "float": "left" })
                                            .prependTo(element);
            } else {
                if (opts.primaryIcon) {
                    $("<span/>").addClass("d-button-primary-icon")
                                        .addClass(opts.primaryIcon)
                                        .css({ "float": "left" })
                                        .appendTo(element);
                }
            }

            if (opts.secondaryIconImage) {
                $("<img alt=''/>").addClass("d-button-secondary-icon")
                                           .attr("src", opts.secondaryIconImage)
                                           .css({ "float": "right" })
                                           .appendTo(element);
            } else {
                if (opts.secondaryIcon) {
                    $("<span/>").addClass("d-button-secondary-icon")
                                        .addClass(opts.secondaryIcon)
                                        .css({ "float": "right" })
                                        .appendTo(element);
                }
            }
        },
        _triggerEvent: function (eventName, eventArgs) {
            this.element.trigger(this.widgetEventPrefix + eventName, eventArgs);
        },
        _checkbox: function () {
            var self = this, el = this.element,
            $val = $(".d-button-value", el), _ischecked = false;
            el.addClass("d-checkbox");
            if ($val.length == 0)
                $val = $("<input type='hidden'/>").addClass("d-button-value").appendTo(el);
            else
                _ischecked = $val.val() == "true" ? true : false;

            if ((this.options.states) && (this.options.states.length))
                self._initState();
            else {
                this.options.states = [];
                this.options.states.push({
                    primaryIcon: "d-checkbox-unchecked",
                    value: false
                });
                this.options.states.push({
                    primaryIcon: "d-checkbox-checked",
                    value: true
                });

                self._initState();
                if (_ischecked)
                    self._nextState();

                this.options.primaryIcon = "d-checkbox-unchecked";
            }
            self._linkbutton();
        },
        _radiobox: function () {
            var self = this, el = this.element,
            $val = $(".d-button-value", el);
            this.options.radio = true;
            el.addClass("d-radio");
            if (self.options.group) el.addClass(self.options.group);

            if ($val.length == 0) {
                $val = $("<input type='hidden'/>").addClass("d-button-value").appendTo(el);
            }

            if ((this.options.states) && (this.options.states.length))
                self._initState();
            else {
                this.options.states = [];
                this.options.states.push({
                    primaryIcon: "d-radio-unchecked",
                    value: false
                });
                this.options.states.push({
                    primaryIcon: "d-radio-checked",
                    value: true
                });

                self._initState();
                this.options.primaryIcon = "d-radio-unchecked";
            }
            self._linkbutton();
        },
        _linkbutton: function () {
            var el = this.element, self = this;
            el.addClass("d-link-button")
               .wrapInner($("<a/>").addClass("d-button-link"));

            var $link = $(">.d-button-link", el);

            $link.attr("target", self.options.target);

            if (this.options.linkUrl)
                $link.attr("href", this.options.linkUrl);
            else
                $link.attr("href", "javascript:void(0);");
            self._createIcons($link);
            if (this.options.imageUrl)
                this._imagebutton();
            if (self.options.splitButton) self._createSpliter();

        },
        _imagebutton: function () {
            var self = this;
            self.element.addClass("d-image-button");
            if (this.options.imageUrl) {

                if (this.options.isbg) {
                    var $parent = $(">.d-button-link", this.element);

                    if ($parent.length == 0) {
                        self.element.wrapInner($("<div />").addClass("d-button-img"));
                        $parent = $(".d-button-img", self.element);
                    }

                    $parent.css({
                        "background-image": "url(" + this.options.imageUrl + ")",
                        "height": self.element.height(),
                        "background-repeat": "no-repeat"
                        //                        "padding-top": "8%",
                        //                        "text-align": "center",
                        //                        "display":"block"
                    });

                    if (this.options.hoverImage)
                        $parent.bind("mouseenter", function () { $(this).css({ "background-image": "url(" + self.options.hoverImage + ")" }); })
                                        .bind("mouseleave", function () { $(this).css({ "background-image": "url(" + self.options.imageUrl + ")" }); });

                    if (this.options.downImage)
                        $parent.bind("mousedown", function () { $(this).css({ "background-image": "url(" + self.options.downImage + ")" }); })
                              .bind("mouseup", function () { $(this).css({ "background-image": "url(" + self.options.imageUrl + ")" }); });
                }
                else { // not bg
                    var $plink = $(">.d-button-link", this.element);
                    var $img = $("<img alt=''/>").addClass("d-button-img")
                                                                 .attr("src", self.options.imageUrl);
                    if ($plink.length)
                        $img.appendTo($plink);
                    else
                        $img.appendTo(this.element);

                    if (self.options.hoverImage) {
                        $img.bind("mouseenter", function () { $(this).attr("src", self.options.hoverImage); })
                               .bind("mouseleave", function () { $(this).attr("src", self.options.imageUrl); });
                    }

                    if (this.options.downImage)
                        $img.bind("mousedown", function () { $(this).data("src", $(this).attr("src")); $(this).attr("src", self.options.downImage); })
                        .bind("mouseup", function () { $(this).attr("src", $(this).data("src")); });
                }
            }
        },
        _standard: function () {
            var el = this.element, self = this;
            el.addClass("d-button");
            self._createIcons(el);
            if (self.options.splitButton) self._createSpliter();
        },
        destroy: function () {
            $.Widget.prototype.destroy.call(this);
        }
    });

    $.widget("ui.colorpicker", {
        options: {
            dropdown: false,
            showClear: true,
            allowInput: true,
            imgUrl: null,
            clientClick: null,
            value: "#ffffff"
        },
        _create: function () {
            var self = this, el = this.element;
            el.addClass("d-colorpicker");
            if (this.options.clientClick)
                el.bind(this.widgetEventPrefix + "clientClick", this.options.clientClick);

            var palette = $("<div/>").addClass("d-colorpicker-palette-holder")
                                                  .appendTo(el);

            var pl = $("<span/>").addClass("d-colorpicker-palette")
                                             .appendTo(palette);

            $("<input value='#ffffff'/>").addClass("d-colorpicker-name")
                                                       .appendTo(palette);

            var cls = $("<span/>").addClass("d-colorpicker-clear")
                                              .attr("title", "No color")
                                              .appendTo(palette);

            var far = $("<div/>").addClass("farbtastic")
                                           .appendTo(el);

            far.farbtastic($(">input", palette));
            far.css({ "top": "0px" });

            $(">input", palette).bind(($.browser.msie ? "onpropertychanged" : "DOMAttrModified"), function () {
                pl.css({
                    "background-color": $(this).val()
                });
                self.options.value = $(this).val();
                self.element.trigger(self.widgetEventPrefix + "clientClick", { value: $(this).val() });
            });

            if (this.options.showClear) {
                cls.click(function (event) {
                    event.stopPropagation();
                    $(">input", palette).val("#ffffff");
                    pl.css({ "background-color": "#ffffff" });
                });
            }
            else
                cls.hide();

            if (this.options.dropdown) {
                var $dc = $("<div/>").addClass("d-colorpicker-button").insertBefore(this.element)
                , $pl = null;

                if (this.options.imgUrl) {
                    $pl = $("<img alt=''/>").addClass("d-colorpicker-palette")
                                                        .attr("src", this.options.imgUrl)
                                                        .appendTo($dc);
                }
                else {
                    $pl = pl.clone().appendTo($dc);
                }

                $pl.click(function () {
                    self.element.trigger(self.widgetEventPrefix + "clientClick", { value: $(">input", palette).val() });
                });

                $("<span/>").addClass("d-colorpicker-icon")
                             .appendTo($dc)
                             .click(function (event) {
                                 event.stopPropagation();
                                 if (!el.hasClass("d-state-open"))
                                     el.dropdownable("open");
                                 else
                                     el.dropdownable("close");
                             });

                this.element.dropdownable({
                    target: $dc,
                    closed: function () {
                        $pl.css("background-color", $(">input", palette).val());
                    }
                });
            }
        },
        destroy: function () {
            $.Widget.prototype.destroy.call(this);
        }
    });

    $.widget("ui.combo", {
        options: {
            dropdownStyle: "dropdown", //dropdown dropdownlist
            filterMode: false,
            source: null,
            selectedValue: null,
            selectedItem: null,
            dataTextField: "span",
            dataValueField: "input[type='hidden']",
            value: null,
            text: null,
            selected: null,
            cssClass: null,
            hoverClass: null,
            itemClass: null,   // "ui-widget-content",
            itemHoverClass: null, // "ui-state-hover",
            itemSelectedClass: null, // "ui-state-highlight"
            itemTemplate: null,
            particalLoad: false,
            autofit: false
        },
        _create: function () {
            var self = this, opts = this.options, eventPrefix = this.widgetEventPrefix, el = this.element;
            this._prepareUI();
            _hoverHandler = function (event) {
                if (opts.hoverClass)
                    self.container.toggleClass(opts.hoverClass);
                self.container.toggleClass("d-combo-hover");
            };

            this.dropdownButton = $("<span />").addClass("d-combo-button")
                                                                      .appendTo(this.container)
                                                                      .bind("mouseenter", _hoverHandler)
                                                                      .bind("mouseleave", _hoverHandler)
                                                                      .bind("click", self._delegate(self, self._onclick));
            $(document).bind("click", self._delegate(self, self.deactive));

            if (opts.selected)
                el.bind(eventPrefix + "selected", opts.selected);

            this.textField.bind("mouseenter", _hoverHandler)
                            .bind("mouseleave", _hoverHandler)
                            .bind("click", self._delegate(self, self._onclick))

            if (this.options.dropdownStyle == "dropdownlist") {
                el.parent().addClass("d-combo-dropdown");
                this.textField.disableSelection();
            }
            else {
                if (this.options.filterMode)
                    this.textField.bind("keyup", self._delegate(self, self._onfilter));
            }

            if (opts.selectedValue) {
                this._setOption("selectedValue", opts.selectedValue);
            }
        },
        _setOption: function (key, value) {
            if (key == "selectedValue") {
                var self = this;
                if (!this.loaded) {
                    this.dataBind(function () {
                        self.loaded = true;
                        //Here maybe has bug.
                    });
                }
                var _input = this.panel.children(".d-combo-item-container").find("input[value='" + value + "']");
                if (_input.length)
                    this.select(null, $(_input).closest("li"));
            }
        },
        _onfilter: function (e, element) {
            if (this.element.val()) {
                var items = this.panel.find(".d-combo-item:not(:contains('" + this.element.val() + "'))");
                if (items.length) items.hide();
            }
            else
                this.panel.find(".d-combo-item").show();
            this.active(e);
        },
        _delegate: function (context, handler) {
            return function (e) {
                handler.apply(context, [e, this]);
            };
        },
        _onclick: function (event) {
            event.stopPropagation();
            if (this.element.parent().hasClass("d-combo-open"))
                this.deactive(event);
            else
                this.active(event);
        },
        search: function (term) {
        },
        setValue: function (txt, _val) {
            this.textField.val(txt);
            if (_val) this.element.val(_val);
            else
                this.element.val(txt);
            this.deactive();
        },
        select: function (event, element) {
            if (element) {
                /*------------------begin set value and text------------------------------*/
                var txtField = this.options.dataTextField ? this.options.dataTextField : "input:first",
                valField = this.options.dataValueField ? this.options.dataValueField : "input:first",
                $txt = $(element).find(txtField),
                $val = $(element).find(valField);

                if ($txt.length) {
                    if ($txt.get(0).tagName == "INPUT")
                        this.textField.val($txt.val())
                    else
                        this.textField.val($txt.text());
                };

                if ($val.length) {
                    var _v = "";
                    if ($val.get(0).tagName == "INPUT")
                        _v = $val.val(); else
                        _v = $val.text();
                    this.element.val(_v);
                    this.options.selectedValue = _v;
                    if ($txt.length == 0) this.textField.val(_v);
                }
                /*------------------end set value and text-------------------------------*/
                var $items = $(element).siblings(".d-combo-item-selected");
                $items.removeClass("d-combo-item-selected");
                if (this.options.itemSelectedClass) {
                    $items.removeClass(this.options.itemSelectedClass);
                    $(element).addClass(this.options.itemSelectedClass);
                }
                $(element).addClass("d-combo-item-selected");
                this.options.selectedItem = element;
                //this.element.trigger(this.widgetEventPrefix + "selected", element);
            }
            this.deactive(event);
        },
        active: function (event) {
            var self = this;
            if (!this.loaded) {
                this.dataBind(function () {
                    self.loaded = true;
                    self._play();
                });
                return;
            }
            this._play();
        },
        _play: function () {
            var others = $("body").find(".d-combo-open");
            if (others.length) {
                others.each(function (i, n) {
                    $(n).children("input").combo("deactive");
                });
            }
            this.element.parent().addClass("d-combo-open");
            this.panel.show("slide", { direction: "up" }, 100);
        },
        deactive: function (event) {
            if (this.element.parent().hasClass("d-combo-open")) {
                this.panel.hide("slide", { direction: "up" }, 100);
                this.element.parent().removeClass("d-combo-open");
                var _hs = this.element.find(".d-combo-item-hover");
                if (_hs.length) _hs.removeClass("d-combo-item-hover");
            }
        },
        _contains: function (parent, child) {
            try {
                return $.contains(parent, child);
            } catch (e) {
                return false;
            }
        },
        dataBind: function (fn) {
            var src = this.options.source;
            if (src) {
                if ($.type(src) == "string")
                    return this.bindToRemote(src, fn);
                if ($.isArray(src))
                    this.bindToArray(src);
                if (src.jquery)
                    this.bindToElement(src);
                if ($.isFunction(fn)) fn();
            }
        },
        bindToArray: function (args) {
            var $ul = $("<ul />").appendTo("body");       //.addClass("d-combo-item-container")

            $.each(args, function (i, n) {
                var $li = $("<li />").appendTo($ul);
                if ($.type(n) == "string") {
                    $("<a href='#'>" + n + "<input type='hidden' value='" + n + "'></a>").appendTo($li);
                }
                else {
                    if (n.selected)
                        $li.addClass("d-combo-item-selected");
                    $("<a href='#'>" + n.label + "<input type='hidden' value='" + n.value + "'></a>").appendTo($li);
                }
            });
            this.bindToElement($ul);
        },
        _particalLoad: function () {
            var self = this;
            if (this._routeValues) {
                var _rvalues = self._routeValues;
                if (_rvalues.total >= _rvalues.index) {
                    var $ul = $(".d-combo-item-container", self.element.parent());
                    $.ajax({
                        type: "POST",
                        data: { size: _rvalues.size, index: _rvalues.index },
                        url: this.options.source,
                        dataType: "json",
                        beforeSend: function () {
                            self._createLoader();
                        },
                        success: function (data) {
                            $("#" + self.options.itemTemplate).tmpl(data.Model).appendTo($ul);
                            self._initItems($ul.find("li:not(.d-combo-item)"));
                            self._routeValues.index++;
                            self._removeLoader();
                        }
                    });
                }
            }
        },
        bindToRemote: function (uri, fn) {
            var self = this;
            this._routeValues = null;

            if (self.options.particalLoad) {
                this._routeValues = {
                    size: 20,
                    index: 1
                };
            }

            $.ajax({
                url: uri,
                type: "POST",
                data: this._routeValues,
                dataType: "json",
                beforeSend: function () {
                    self.dropdownButton.addClass("d-combo-load");
                },
                success: function (data) {
                    if ((self.options.itemTemplate) && ($.fn.tmpl)) {
                        var $ul = $("<ul />").appendTo("body");

                        $("#" + self.options.itemTemplate).tmpl(data.Model).appendTo($ul);
                        self._routeValues.count = data.Total;
                        self._routeValues.total = Math.round(data.Total / self._routeValues.size);
                        self._routeValues.index++;
                        self.bindToElement($ul);
                        self.dropdownButton.removeClass("d-combo-load");
                        var panel = $(".d-combo-panel", self.element.parent());
                        panel.bind("scroll", function (event) {
                            var st = panel.scrollTop(),
                            ph = panel.height(),
                            ch = $ul.height();

                            if ((ch - st) <= ph) {
                                self._particalLoad();
                            }
                        });
                    }
                    else
                        self.bindToArray(data);
                    if ($.isFunction(fn)) fn();
                }
            });
        },
        _removeLoader: function () {
            var loader = $(".d-loader", this.element.parent());
            if (loader.length) loader.remove();
        },
        _createLoader: function () {
            var _loader = $("<div/>").addClass("d-loader d-combo-load").appendTo(this.element.parent());
            _loader.css({
                height: this.panel.height() + "px",
                width: this.panel.width() + "px",
                "left": "0px",
                "top": this.panel.position().top + "px"
            });
            return _loader;
        },
        bindToCallback: function (callback, fn) {
            var self = this;
            if ($.isFunction(callback)) {
                callback(function (items) {
                    self.bindToArray(items);
                    if ($.isFunction(fn)) fn();
                });
            }
        },
        _initItems: function ($items) {
            var self = this;
            $items.addClass("d-combo-item" + (self.options.itemClass ? " " + self.options.itemClass : ""))

                              .disableSelection();

            $items.each(function (i, n) {
                $(n).bind("mouseenter", function (event) {
                    event.stopPropagation();
                    $(this).addClass("d-combo-item-hover");
                    if (self.options.itemHoverClass)
                        $(this).addClass(self.options.itemHoverClass);
                })
                                .bind("mouseleave", function (event) {
                                    event.stopPropagation();
                                    $(this).removeClass("d-combo-item-hover");
                                    if (self.options.itemHoverClass)
                                        $(this).removeClass(self.options.itemHoverClass);
                                })
                                 .click(function (event) {
                                     event.stopPropagation();
                                     if (self.options.itemHoverClass)
                                         $items.removeClass(self.options.itemHoverClass);
                                     self.select(event, this);

                                     self.element.trigger(self.widgetEventPrefix + "selected", { item: $(this), value: self.options.selectedValue });
                                     //self.element.trigger(self.widgetEventPrefix + "selected", {sender:this,});
                                 });
            });
        },
        bindToElement: function (element) {
            if ((element) && (this.panel)) {
                //if (!this._contains(this.panel, element)) {
                if (!element.hasClass("d-combo-item-container")) {
                    var self = this;
                    this.panel.append(element);

                    element.addClass("d-combo-item-container")
                                .css("display", "block").disableSelection();
                    var $items = element.children("li");
                    self._initItems($items);
                }
            }
        },

        _prepareUI: function () {
            var element = this.element;
            if (!element.parent().hasClass("d-combo")) {
                element.wrap(
                             $('<div/>').addClass('d-combo')
                //.css({
                // width: (element.outerWidth(true) + 20) + "px"
                //})
                             );
                this.container = element.parent();

                if (this.options.autofit) {
                    //this.container.width(this.container.parent().innerWidth(true));
                    this.container.css({ width: "auto", display: "block" });
                    this.element.width(this.container.width() - 24);
                }
                else {
                    if (element.width()) {
                        //this.container.width(element.width());
                        this.element.width(element.width() - 20);
                    }
                }


                this.textField = $("<input />").addClass("d-combo-input")
                                                             .prependTo(this.container);
                if (element.attr("style"))
                    this.textField.attr("style", element.attr("style"));
                element.hide();

                if (this.options.text) this.textField.val(this.options.text);
                if (this.options.value) this.element.val(this.options.value);


                //prepare dropdownPanel
                var _pane = $("<div/>").addClass("d-combo-panel")
                               .css({
                                   "min-width": this.container.width() + "px",
                                   "position": "absolute",
                                   "left": "0px",
                                   "top": this.container.outerHeight(true) ? (this.container.outerHeight(true) + "px") : "23px"
                               })
                               .appendTo(this.container);

                this.panel = _pane;
                _pane.hide().disableSelection();
            }
        },
        addItem: function (_text, _value) {
            var item = $("<li/>"),
            _valEl = $("<input type='hidden' />").val(_value),
            _txtEl = $("<span/>").text(_text),
            $ul = $(".d-combo-item-container", self.element.parent());

            item.append(_valEl)
                   .append(_txtEl);
            $ul.append(item);
        },
        destroy: function () {
            $.Widget.prototype.destroy.call(this);
        }
    });

    $.widget("ui.dropdownable", {
        options: {
            target: null,
            showEffect: "slide",
            hideEffect: "slide",
            pos: "left bottom",
            opened: null,
            closed: null,
            speed: 100,
            fx: { direction: "up" }
        },
        _create: function () {
            var self = this, el = this.element, eventPrefix = this.widgetEventPrefix;
            if (this.options.opened)
                el.bind(eventPrefix + "opened", this.options.opened);
            if (this.options.closed)
                el.bind(eventPrefix + "closed", this.options.closed);
            $(document).bind("click", function () {
                self.close();
            });

            el.addClass("d-dropdownable");
            if (this.options.target) {
                el.position({
                    my: "left top",
                    at: self.options.pos,
                    of: $(this.options.target),
                    collision: "flip"
                }).hide();
            }
        },
        open: function () {
            var self = this;
            if (this.element.hasClass("d-state-open")) return;

            clearTimeout(self.element.data("timer"));

            if (this.options.target) {
                var _pos = $(self.options.target).position(),
                t = (_pos.top + $(self.options.target).outerHeight(true)) + "px",
                l = _pos.left + "px";

                self.element.css({ top: t, left: l });

                //                self.element.position({
                //                    my: "left top",
                //                    at: self.options.pos,
                //                    of: $(self.options.target)
                //                }).hide();
            }

            self.element.data("timer", setTimeout(function () {
                self.element.show(self.options.showEffect, self.options.fx, self.options.speed, function () {
                    self.element.addClass("d-state-open");
                    self._triggerEvent("opened");
                });
            }, 100));
        },
        close: function () {
            var self = this;
            if (this.element.hasClass("d-state-open")) {
                clearTimeout(self.element.data("timer"));
                self.element.data("timer", setTimeout(function () {
                    self.element.hide(self.options.hideEffect, self.options.fx, self.options.speed, function () {
                        self.element.removeClass("d-state-open");
                        self._triggerEvent("closed");
                    });
                }, 100));
            }
        },
        _triggerEvent: function (eventName, eventArgs) {
            this.element.trigger(this.widgetEventPrefix + eventName, eventArgs);
        },
        destroy: function () {
            $.Widget.prototype.destroy.call(this);
        }
    });
    $.widget("ui.editable", {
        options: {
            submit: null,
            cancel: null
        },
        _create: function () {
            var self = this, opts = this.options, el = this.element;
            if (opts.submit)
                el.bind("submitchanged", opts.submit);
            if (opts.cancel)
                el.bind("canceledit", opts.cancel);

            el.bind("click", function () {
                self.edit();
            });
        },
        edit: function () {
            var el = this.element, self = this;
            if (el.attr("editing"))
                return;
            el.attr("editing", true);
            //el.data("editing", true);

            var $editbox = $("<input type='text' />");
            $editbox.css({
                "border": "none",
                "background": "none",
                "width": (el.width()) + "px"
                //"dipslay": "inline"
            });
            var _innerText = el.text();
            $editbox.val(_innerText);
            $editbox.css({
                "font-family": el.css("font-family"),
                //"font-size": el.css("font-size"),
                "color": el.css("color")
            });
            el.data("_text", _innerText);
            el[0].innerHTML = "";
            el.append($editbox);


            $editbox.bind("keypress", function (event) {
                if (event.keyCode == 13) self._submitchange();
                if (event.keyCode == 27) self._canceledit();
            });

            $editbox.bind("blur", function () { self._submitchange(); });

            $editbox.focus();
            if ($.browser.msie) {
                var txtRange = $editbox[0].createTextRange();
                txtRange.select();
            }
        },
        _canceledit: function () {
            var el = this.element;
            this._removeEditor();
            this.element.text(el.data("_text"));
            this.element.trigger("canceledit");
            this.element.removeAttr("editing");
        },
        _removeEditor: function () {
            var el = this.element;
            var $input = el.find("input");
            $input.unbind();
            $input.remove();
        },
        _submitchange: function () {
            var el = this.element;
            var $input = el.find("input");
            el.text($input.val());
            el.trigger("submitchanged", $input.val());
            el.removeAttr("editing");
            this._removeEditor();
        },
        destroy: function () {
            this.element.unbind();
            $.Widget.prototype.destroy.call(this);
        }
    });

    $.widget("ui.dgrid", {
        options: {
            showScroll: false,
            sortable: true,
            groupable: true,
            sort: null,
            columnClick: null,
            selectedRow: null,
            rowSelected: null,
            addGroup: null,
            delGroup: null,
            filters: null,
            filterChanged: null
        },
        _create: function () {
            var self = this, el = this.element, eventPrefix = this.widgetEventPrefix;
            this.element.addClass("d-grid");

            this.header = $(".d-grid-header", el);
            this.footer = $(".d-grid-footer", el);
            this.columns = $(".d-grid-column", el);
            this.columnsArea = $(".d-grid-columns", el);
            this.dataArea = $(".d-grid-data-area", el);

            if (this.options.showScroll) {
                var h = this.element.height();
                this.element.addClass("d-grid-scrolling");
                self.columnsArea.css("overflow", "hidden");
                this.dataArea.height(h - this.header.height() - this.footer.height() - this.columnsArea.height() - 40)
                           .bind("scroll", function () {
                               self.columnsArea.scrollLeft(self.dataArea.scrollLeft());
                           });
            }

            if (this.options.filterChanged)
                this.element.bind(eventPrefix + "filterChanged", this.options.filterChanged);

            if (this.options.columnClick)
                this.element.bind(eventPrefix + "columnClick", this.options.columnClick);

            if (this.options.sort)
                this.element.bind(eventPrefix + "sort", this.options.sort);

            if (this.options.rowSelected)
                this.element.bind(eventPrefix + "rowSelected", this.options.rowSelected);

            if (this.options.addGroup)
                this.element.bind(eventPrefix + "addGroup", this.options.addGroup);

            if (this.options.delGroup)
                this.element.bind(eventPrefix + "delGroup", this.options.delGroup);

            this.columns.bind("click", function () {
                self._clearselection();
                $(this).addClass("d-grid-column-selected");
                var $cells = $("." + $(this).attr("id"), self.dataArea);
                $cells.addClass("d-grid-cell-selected");
                if (self.options.sortable) {
                    var _fieldName = $(this).find("input[type='hidden']");
                    var _asc = $(this).hasClass("d-grid-column-asc");

                    if ($(".d-grid-column-sorting-icon", this).length == 0) {
                        $("<span/>").addClass("d-grid-column-sorting-icon").appendTo($("a", this));
                        _asc = false;
                    }

                    if (_asc) {
                        $(this).removeClass("d-grid-column-asc");
                        $(this).addClass("d-grid-column-desc");
                        _asc = false;
                    }
                    else {
                        $(this).removeClass("d-grid-column-desc");
                        $(this).addClass("d-grid-column-asc");
                        _asc = true;
                    }

                    $(this).siblings().each(function (i, n) {
                        var $c = $(n),
                        $icon = $(".d-grid-column-sorting-icon", $c);

                        $c.removeClass("d-grid-column-desc")
                           .removeClass("d-grid-column-asc");

                        if ($icon.length) $icon.remove();
                    });

                    self._triggerEvent("sort", { field: _fieldName.val(), order: _asc ? "asc" : "desc" });
                }
                self._triggerEvent("columnClick", this);
            });

            this._initresizer();
            this._initrows();
            if (this.options.groupable)
                this._initgrouping();
            this._setColHeadersWidth();
        },
        _setColHeadersWidth: function () {
            //            var colTbl = $(">.d-grid-columns>table", this.element),
            //            datTbl = $(">d-grid-data-area>.d-grid-data-table", this.element);
            //            //if (datTbl.find(".d-grid-grouping-row").length == 0) {
            //                if (datTbl.children("colgroup").length) datTbl.children("colgroup").remove();
            //                datTbl.prepend(colTbl.children("colgroup").clone());
            //            //}
        },
        _initgrouping: function () {
            var self = this;
            $(".d-grid-groups", self.element).sortable({
                forceHelperSize: true,
                forcePlaceholderSize: true,
                placeholder: "ui-state-highlight"
            });

            $(".d-grid-groups", self.element).droppable({
                activeClass: "ui-state-active",
                hoverClass: "ui-state-highlight",
                over: function (event, ui) {
                    if (ui.helper.hasClass("d-grid-group-helper")) {
                        var _exists = $("." + ui.draggable.attr("id"), this);
                        if (_exists.length == 0)
                            ui.helper.addClass("d-grid-group-allowdrop");
                    }
                },
                out: function (event, ui) {
                    if (ui.helper.hasClass("d-grid-group-helper"))
                        ui.helper.removeClass("d-grid-group-allowdrop");
                },
                drop: function (event, ui) {
                    if (ui.helper.hasClass("d-grid-group-allowdrop")) {
                        var _emptyElement = $(".d-grid-group-empty", this);
                        if (_emptyElement.length) _emptyElement.hide();
                        var _gl = $("<li/>").addClass(ui.draggable.attr("id"))
                                                    .appendTo(this);
                        if (ui.draggable.hasClass("d-grid-column-asc"))
                            _gl.addClass("d-grid-column-asc");

                        if (ui.draggable.hasClass("d-grid-column-desc"))
                            _gl.addClass("d-grid-column-desc");

                        _gl.html(ui.draggable.html());
                        var $link = _gl.find("a");
                        $("<span/>").addClass("d-grid-group-remove-icon")
                                            .appendTo($link)
                                            .click(function () {
                                                _gl.remove();
                                                self.columnsArea.find(".d-grid-column:first").remove();
                                                if (self._getGroups().length == 0) {
                                                    _emptyElement = $(".d-grid-group-empty", $(".d-grid-groups", self.element));
                                                    if (_emptyElement.length) _emptyElement.show();
                                                }
                                                self._triggerEvent("delGroup", { groups: self._getGroups() });
                                            });

                        if ($link.find(".d-grid-column-sorting-icon").length == 0) {
                            _gl.addClass("d-grid-column-asc");
                            ui.draggable.addClass("d-grid-column-asc");
                            $("<span/>").addClass("d-grid-column-sorting-icon").appendTo($link);
                            $("<span/>").addClass("d-grid-column-sorting-icon").appendTo(ui.draggable.find("a"));
                        }

                        $link.click(function () {
                            ui.draggable.click();
                        });
                        $("<th/>").addClass("d-grid-column").prependTo(self.columnsArea.find(".d-grid-column:first").parent());
                        self._triggerEvent("addGroup", { groups: self._getGroups() });
                    }
                }
            });

            self.columns.draggable({
                appendTo: self.element,
                helper: function (event) {
                    return $("<div/>").addClass("d-grid-group-helper")
                                                .text($(this).text());
                },
                iframeFix: true
            });

            /*---------init added groups-----------*/
            var $addedGroups = $(".d-grid-groups", self.element).children("li:not(.d-grid-group-empty)");
            if ($addedGroups.length) {
                $addedGroups.each(function (i, n) {
                    $(n).find("a").click(function () {
                        var colName = $(this).siblings("input").val();
                        var colInstance = self._getColumn(colName);
                        colInstance.click();
                    });

                    $(n).find(".d-grid-group-remove-icon").click(function () {
                        $(n).remove();
                        self.columnsArea.find(".d-grid-column:first").remove();
                        if (self._getGroups().length == 0) {
                            _emptyElement = $(".d-grid-group-empty", $(".d-grid-groups", self.element));
                            if (_emptyElement.length) _emptyElement.show();
                        }
                        self._triggerEvent("delGroup", { groups: self._getGroups() });
                    });
                });
            }


        },
        _getColumn: function (colName) {
            var self = this;
            var result = null;
            self.columns.each(function (i, n) {
                var $hidden = $(n).find("input[type='hidden']");
                if ($hidden.length) {
                    if ($hidden.val() == colName) {
                        result = $(n);
                        return false;
                    }
                }
            });
            return result;
        },
        getGroups: function () {
            return this._getGroups();
        },
        _getGroups: function () {
            var _groups = [];
            $(".d-grid-groups", this.element).find("input").each(function (i, n) {
                $val = $(n);
                _groups.push($val.val());
            });
            return _groups;
        },
        _initresizer: function () {
            var self = this, resizHandler = function (event) {
                var $resizer = $(".d-grid-resizing", self.columnsArea);
                if ($resizer.length) {
                    var x = event.clientX;
                    $resizer.css("left", x + "px");
                    $(".d-grid-resize-helper", el).css("left", x + "px");

                    var targetCol = $resizer.data("column"),
                    _offsetX = x - $resizer.data("orgX"),
                    _nw = $resizer.data("orgWidth") + _offsetX;

                    targetCol.width(_nw + "px");

                    var relativeCols = $("." + targetCol.attr("id"), self.dataArea);
                    if (relativeCols.length)
                        relativeCols.width(_nw + "px");

                    var resizers = $resizer.siblings(".d-grid-resize-handler");
                    if (resizers.length) {
                        resizers.each(function (i, n) {
                            $(n).position({
                                my: "right top",
                                at: "right top",
                                of: $(n).data("column")
                            });
                        });
                    }
                }
            };

            var setSizeHandler = function (event) {
                var hResizing = $(".d-grid-resizing", self.columnsArea);
                if (hResizing.length) {
                    $(".d-grid-resize-helper", el).remove();
                    hResizing.removeClass("d-grid-resizing");
                }
            };

            //create column resizer
            self.columns.each(function (i, n) {
                var $col = $(n);
                if ($col.hasClass("d-grid-column-resizable")) {
                    var $rshandler = $("<div/>").addClass("d-grid-resize-handler").appendTo(self.columnsArea);

                    $rshandler.bind("mousedown", function () {
                        self._createResizeHelper($rshandler);
                        $rshandler.addClass("d-grid-resizing")
                                        .data("orgX", $rshandler.position().left)
                                        .data("orgWidth", $col.width());
                    })
                    .bind("mousemove", resizHandler)
                    .bind("mouseup", setSizeHandler)
                    .position({
                        my: "right top",
                        at: "right top",
                        of: $col
                    })
                    .data("column", $col);
                }
            });

            self.columnsArea.bind("mousemove", resizHandler)
                          .bind("mouseup", setSizeHandler);
        },
        _clearselection: function () {
            var selCells = $(".d-grid-cell-selected", this.dataArea);
            $(".d-grid-column", this.element).removeClass("d-grid-column-selected");
            if (selCells.length) selCells.removeClass("d-grid-cell-selected");
        },
        _triggerEvent: function (eventName, eventArgs) {
            this.element.trigger(this.widgetEventPrefix + eventName, eventArgs);
        },
        _initrows: function () {
            var $rows = $(".d-grid-row", this.dataArea), self = this;
            if ($rows.length) {

                $rows.click(function () {
                    self._clearselection();
                    $(".d-grid-cell", $(this)).addClass("d-grid-cell-selected");
                    self.options.selectedRow = this;
                    var _tmplItem = $(this).tmplItem(), _data = null;
                    if (_tmplItem)
                        _data = _tmplItem.data;

                    self._triggerEvent("rowSelected", { row: this, data: _data });
                });

                $rows.each(function (i, _r) {
                    if ((i % 2) != 0)
                        $(_r).addClass("d-grid-row-alt");
                });
            }

            /*-------------init group holder--------------------*/
            var $gHolder = self.dataArea.find(".d-grid-group-holder");
            $gHolder.each(function (i, n) {
                var $holder = $(n), parentRow = $holder.closest("tr"),
                 childrenRows = parentRow.nextUntil("tr[level='" + parentRow.attr("level") + "']"),
                 parentLevel = parseInt(parentRow.attr("level"));

                //if (childrenRows.length) {
                $holder.toggle(function () {
                    $(this).addClass("d-grid-group-collapse");

                    childrenRows.each(function (i, r) {
                        var rowLevel = parseInt($(r).attr("level"));
                        if (rowLevel > parentLevel)
                            $(r).hide();
                    });

                }, function () {
                    $(this).removeClass("d-grid-group-collapse");
                    childrenRows.each(function (i, r) {
                        var rowLevel = parseInt($(r).attr("level"));
                        if (rowLevel > parentLevel)
                            $(r).show();
                    });
                });
            });

            var $detailButtons = self.dataArea.find(".d-grid-detail-button");
            $detailButtons.each(function (i, n) {
                var dButton = $(n), nextDetailRow = $(n).closest(".d-grid-row").next(".d-grid-row-detail");

                dButton.click(function () {
                    if (!$(this).parent().hasClass("d-grid-detail-collapse")) {
                        $(this).parent().addClass("d-grid-detail-collapse");
                        if (nextDetailRow.length) { nextDetailRow.hide(); }
                    }
                    else {
                        if ($(this).children("a").length > 0) {
                            var _parent = $(this).parent(), _link = $(this).children("a"),
                            _loader = self._createLoader();
                            nextDetailRow.find(".d-grid-detail").load(_link.attr("href"), function () {
                                _parent.removeClass("d-grid-detail-collapse");
                                _link.remove();
                                _loader.remove();
                                if (nextDetailRow.length) { nextDetailRow.show(); }
                            });

                        } else {
                            $(this).parent().removeClass("d-grid-detail-collapse");
                            if (nextDetailRow.length) { nextDetailRow.show(); }
                        }
                    }
                });
            })
        },
        load: function (remoteUrl, routeData, tmplName, method, callback) {
            var self = this, $dataContainer = this.options.showScroll ? $(">.d-grid-data-area>table>tbody", this.element) : $(">table>.d-grid-data-area", this.element);
            var _loader = null;

            $.ajax({
                type: method,
                data: routeData,
                url: remoteUrl,
                dataType: "json",
                beforeSend: function () {
                    _loader = self._createLoader();
                },
                success: function (data) {
                    $dataContainer.empty();
                    $("#" + tmplName).tmpl(data.Model).appendTo($dataContainer);

                    if (self._getGroups().length)
                        self._reInitGroups();

                    self._initrows();
                    self._setColHeadersWidth();
                    if (_loader) _loader.remove();

                    if ($.isFunction(callback))
                        callback(data);
                }
            });
        },
        _reInitGroups: function () {
            var gCount = this._getGroups().length,
            colCount = this.columnsArea.find(".d-grid-column").length,
            dataRows = this.dataArea.find(".d-grid-row");

            for (var i = 0; i < gCount; i++) {
                var rows = this.dataArea.find(".d-grid-grouping-row[level='" + i.toString() + "']");
                var colspan = colCount - i;

                rows.each(function (_index, n) {
                    var $row = $(n);
                    var $gCell = $row.find(".d-grid-grouping-cell");
                    if ($gCell.length) {
                        if (colspan > 1) $gCell.attr("colspan", colspan.toString());

                        for (var j = 0; j < i; j++)
                            $("<td/>").addClass("d-grid-cell").prependTo($row);
                    }
                });

                dataRows.each(function (dataIndex, dataItem) {
                    $("<td/>").addClass("d-grid-cell").prependTo(dataItem);
                });
            }
            //this._initgrouping();
        },
        _createLoader: function () {
            var _loader = $("<div/>").addClass("d-big-loader").appendTo(this.element), _pos = this.dataArea.position();
            _loader.css({
                top: _pos.top + "px",
                left: _pos.left + "px",
                width: this.dataArea.width() + "px",
                height: this.dataArea.height() + "px"
            });
            return _loader;
        },
        _createResizeHelper: function ($handler) {
            var _helper = $("<div/>").addClass("d-grid-resize-helper").appendTo($(".d-grid-data-area", this.element));
            _helper.css({
                "left": $handler.position().left + "px",
                "height": $(".d-grid-data-area", this.element).height()
            });
            return _helper;
        },
        addFilter: function (_field, _operator, _term, _replaceExists) {
            if (this.options.filters == null) this.options.filters = [];
            if (_replaceExists) this._removeFilter(_field);
            var _formatTerm = _term;
            if (_operator == "startswith") { _formatTerm = "'" + _term + "%'"; }
            if (_operator == "endswith") { _formatTerm = "'%" + _term + "'"; }
            if (_operator == "contains") { _formatTerm = "'%" + _term + "%'"; }
            if (_operator == "not~contains") { _formatTerm = "'%" + _term + "%'"; }

            this.options.filters.push({ field: _field, operator: _operator, term: _formatTerm });
            this._triggerEvent("filterChanged", { filters: this.options.filters, value: this.getFilters() });
        },
        clearFilter: function () {
            this.options.filters = [];
        },
        removeFilter: function (_field) {
            this._removeFilter(_field);
            this._triggerEvent("filterChanged", { filters: this.options.filters, value: this.getFilters() });
        },
        _removeFilter: function (_field) {
            var tmpArgs = [];
            if (this.options.filters) {
                $.each(this.options.filters, function (i, n) {
                    if (n.field != _field)
                        tmpArgs.push(n);
                });

                this.options.filters = tmpArgs;
            }
        },
        setFilters: function (strFilters) {
            if (strFilters) {
                var fargs = strFilters.split("-"), tmpArgs = [];
                $.each(fargs, function (i, n) {
                    var exprArgs = n.split("~");
                    tmpArgs.push({
                        field: exprArgs[0],
                        operator: exprArgs[1],
                        term: exprArgs[2]
                    });
                });
                this.options.filters = tmpArgs;
            }
            else
                this.options.filters = [];
        },
        getFilters: function () {
            var strFilters = "", filterArgs = [];
            $.each(this.options.filters, function (i, n) {
                filterArgs.push(n.field + "~" + n.operator + "~" + n.term);
            });
            strFilters = filterArgs.join("-");
            return strFilters;
        },
        getOrders: function () {
            var strOrders = "", orderArgs = [];
            if (this.columns) {
                $.each(this.columns, function (i, n) {
                    var $col = $(n);
                    if ($col.hasClass("d-grid-column-asc"))
                        orderArgs.push($col.children("input[type='hidden']").val() + "~asc");
                    if ($col.hasClass("d-grid-column-desc"))
                        orderArgs.push($col.children("input[type='hidden']").val() + "~desc");
                });
            }
            strOrders = orderArgs.join("-");
            return strOrders;
        },
        _delegate: function (context, handler) {
            return function (e) {
                handler.apply(context, [e, this]);
            };
        },
        destroy: function () {
            $.Widget.prototype.destroy.call(this);
        }
    });

    $.widget("ui.inputFilter", {
        options: {
            number: false,
            maxlength: false,
            decimalDigits: 0,
            mode: "validchars",
            validChars: null,
            invalidChars: null
        },
        _create: function () {
            var self = this, opts = this.options, el = this.element;
            var numChars = "1234567890";
            if (opts.number) {
                if (isNaN(parseInt(el.val())))
                    el.val(self._getDefaultValue());

                el.bind("change", function () {
                    if (isNaN(parseInt(el.val())))
                        el.val(self._getDefaultValue());
                });
            }

            if (opts.maxlength) {
                el.attr("maxlength", opts.maxlength);
            }

            el.bind("keypress", function (event) {
                var _c = event.charCode;
                if ((_c == undefined) || (_c == 0)) _c = event.keyCode;

                var ignores = [8, 9, 16, 17, 18, 19, 20, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43];
                for (var ig = 0; ig < ignores.length; ig++) {
                    if (ignores[ig] == _c)
                        return true;
                }

                if (opts.number) {
                    if (_c == 46) {
                        if (opts.decimalDigits == 0)
                            return false;

                        if (el.val().indexOf(".") > -1)
                            return false;
                        return true;
                    }
                    //var _smallPads = [96, 97, 98, 99, 100, 101, 102, 103, 104, 105];
                    var _smallPads = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57];
                    for (var s = 0; s < _smallPads.length; s++) {
                        if (_smallPads[s] == _c)
                            return true;
                    }
                    return self._isValid(numChars, _c);
                }

                if (opts.mode == "validchars") {
                    if (opts.validChars)
                        return self._isValid(opts.validChars, _c);
                } else {
                    if (opts.invalidChars)
                        return !self._isValid(opts.invalidChars, _c);
                }

            });
        },
        _getDefaultValue: function () {
            var v = "0";
            if (this.options.decimalDigits) {
                v += ".";
                for (var d = 0; d < this.options.decimalDigits; d++) {
                    v = v + "0";
                }
            }
            return v;
        },
        _isValid: function (chars, code) {
            for (var i = 0; i < chars.length; i++) {
                if (chars.charCodeAt(i) == code)
                    return true;
            }
            return false;
        },
        destroy: function () {
            this.element.unbind("keypress");
            $.Widget.prototype.destroy.call(this);
        }
    });

    $.widget("ui.listbox", {
        options: {
            selected: null,
            edited: null,
            deleted: null,
            changed: null, //triggered when position is changed
            scrollEnd: null,
            droptargets: null,
            dropped: null,
            dropover: null,
            dropout: null,
            itemsloaded: null,
            itemclass: null,
            itemhoverclass: null,
            itemselectedclass: null,
            multiselection: false,
            inline: false,
            dataTextField: ".d-list-item-text",
            dataValueField: "input[type='hidden']",
            checkboxs: false,
            editable: false,
            sortable: false,
            droppable: false,
            selectedItem: null,
            selectedValue: null
        },
        _create: function () {
            var self = this, opts = this.options, el = this.element, eventPrefix = this.widgetEventPrefix;

            if (opts.selected) el.bind(eventPrefix + "selected", opts.selected);
            if (opts.edited) el.bind(eventPrefix + "edited", opts.edited);
            if (opts.deleted) el.bind(eventPrefix + "deleted", opts.deleted);
            if (opts.dropout) el.bind(eventPrefix + "dropout", opts.dropout);
            if (opts.dropover) el.bind(eventPrefix + "dropover", opts.dropover);
            if (opts.dropped) el.bind(eventPrefix + "dropped", opts.dropped);
            if (opts.changed) el.bind(eventPrefix + "changed", opts.changed);
            if (opts.scrollEnd) el.bind(eventPrefix + "scrollEnd", opts.scrollEnd);
            if (opts.itemsloaded) el.bind(eventPrefix + "itemsloaded", opts.itemsloaded);
            el.addClass("d-listbox");

            var $ul = el.children("ul");
            self._initDataContainer($ul);

            el.bind("scroll", function () {
                if (opts.inline) {
                    if (($ul.width() - el.scrollLeft()) <= el.width())
                        self._triggerEvent("scrollEnd", self);
                }
                else {
                    var st = el.scrollTop(),
                            ph = el.height(),
                            ch = $ul.height();

                    if ((ch - st) <= ph) {
                        self._triggerEvent("scrollEnd", self);
                    }
                }
            });

            if (!self.options.checkboxs)
                self._initSelection();
        },
        _initSelection: function () {
            var valElement = $(".d-listbox-values", this.element);
            this.options.selectedValue = valElement.val();
            if (valElement.val()) {
                var items = this.element.find(".d-list-item");
                if (this.options.multiselection) {
                    var vals = valElement.val().split(",");
                    $.each(vals, function (i, v) {
                        var _sel = items.find("input[value='" + v + "']");
                        if (_sel.length) _sel.closest(".d-list-item").addClass("d-list-item-selected");
                    });
                }
                else {
                    var _sel = items.find("input[value='" + valElement.val() + "']");
                    if (_sel.length) _sel.closest(".d-list-item").addClass("d-list-item-selected");
                }
            }
        },
        _contains: function (parent, child) {
            try {
                return $.contains(parent, child);
            } catch (e) {
                return false;
            }
        },
        _initDataContainer: function ($ul) {
            var self = this, opts = this.options, el = this.element;
            if ($ul.length) {
                $ul.addClass("d-list-items-holder")
                     .children().not("d-list-item-disabled").each(function (i, n) {
                         self._initItem(n);
                     });
            }
            else {
                $("<ul/>").addClass("d-list-items-holder").appendTo(el);
            }

            if (this.options.sortable) {
                $ul.sortable({
                    forceHelperSize: true,
                    forcePlaceholderSize: true,
                    placeholder: "d-list-item-placeholder",
                    items: ".d-list-item",
                    update: function (event, ui) {
                        var seq = $ul.find(".d-list-item").index(ui.item);
                        self._triggerEvent("changed", { "item": ui.item, "index": seq });
                    },
                    cancel: ".d-list-item-disabled"
                })

                if (this.options.droptargets)
                    $ul.sortable("option", "connectWith", this.options.droptargets);
            }

            if (this.options.inline) {
                var _items = $ul.find(".d-list-item:visible");
                var _w = 0;
                _items.each(function (i, n) {
                    _w += $(n).outerWidth(true);
                });

                if (_w) {
                    $ul.width(_w);
                    el.css({ "overflow-y": "hidden" });
                }
            }

            if (this.options.droppable) {
                $ul.droppable({
                    greedy: true,
                    over: function (event, ui) {
                        self._triggerEvent("dropout", { "listbox": self, item: ui.draggable, container: $(this) });
                    },
                    out: function (event, ui) {
                        self._triggerEvent("dropover", { "listbox": self, item: ui.draggable, container: $(this) });
                    },
                    drop: function (event, ui) {
                        if (self._contains(this, ui.draggable.get(0)))
                            return;
                        self._triggerEvent("dropped", { "listbox": self, item: ui.draggable, container: $(this) });
                    }
                });
            }
        },
        itemReset: function (element) {
            this._initItem(element);
        },
        _initItem: function (element) {
            var $li = $(element), self = this;
            $li.addClass("d-list-item")
               .bind("click", this._delegate(this, this._onitemclick))
               .bind("mouseenter", function () { $(this).addClass("d-list-item-hover"); })
               .bind("mouseleave", function () { $(this).removeClass("d-list-item-hover"); });

            if (this.options.checkboxs) {
                var _checkbox = $("<input type='checkbox' />").addClass("d-list-item-checkbox").prependTo($li),
                _valItem = _checkbox.closest(".d-list-item").find(this.options.dataValueField),
                _val = $(this.element).children(".d-listbox-values");

                if (_val.val()) {
                    _values = _val.val().split(",");
                    if ($.inArray(_valItem.val(), _values) > -1)
                        _checkbox.attr("checked", true);
                }

                _checkbox.click(function () { self._updateCheckedValues(); });
            }

            if ((this.options.editable) && ($.fn.editable)) {
                var $txt = $li.find(this.options.dataTextField);
                if ($txt.length) {
                    $txt.editable({ submit: function (_val) {
                        self._triggerEvent("edited", { "item": element, "text": _val });
                    }
                    });
                }
            } else $li.disableSelection();
        },
        _delegate: function (context, handler) {
            return function (e) {
                handler.apply(context, [e, this]);
            };
        },
        _triggerEvent: function (eventName, eventArgs) {
            this.element.trigger(this.widgetEventPrefix + eventName, eventArgs);
        },
        _onitemclick: function (e, element) {
            var $li = $(element);
            var _value = $(">.d-listbox-values", this.element);

            if (this.options.multiselection) {
                $li.toggleClass("d-list-item-selected");

                if (!this.options.checkboxs) {
                    if ((this.options.dataValueField) && (_value.length)) {
                        var $lis = $(".d-list-item-selected", element);
                        if ($lis.length) {
                            var selectedValues = new Array();
                            $lis.each(function (i, n) {
                                var $item = $(n);
                                var _v = $item.find(this.options.dataValueField);
                                if (_v.length) {
                                    if (_v.get(0).tagName == "INPUT")
                                        selectedValues.push(_v.val());
                                    else
                                        selectedValues.push(_v.text());
                                }
                            });

                            if (selectedValues.length) _value.val(selectedValues.join(","));
                            else _value.val("");
                        } // end $lis.length
                        else { _value.val(""); }
                    } // end dataValueField and _value.length
                } //end checkbox
            }
            else {
                $li.siblings(".d-list-item-selected").removeClass("d-list-item-selected");
                $li.addClass("d-list-item-selected");

                if (!this.options.checkboxs) {
                    if ((this.options.dataValueField) && (_value.length)) {
                        var _vf = $li.find(this.options.dataValueField);
                        if (_vf.length) {
                            if (_vf.get(0).tagName == "INPUT")
                                _value.val(_vf.val());
                            else
                                _value.val(_vf.text);
                        }
                    }
                    else
                        _value.val($li.text());
                }
            }

            this.options.selectedItem = element;
            this.options.selectedValue = _value.val();
            var _eventArgs = { item: element, value: _value.val(), data: null };
            if ($.tmpl) {
                var tmplElement = $.tmplItem(element);
                if (tmplElement) {
                    if (tmplElement.data)
                        _eventArgs.data = tmplElement.data;
                }
            }
            this._triggerEvent("selected", _eventArgs);
        },
        _updateCheckedValues: function () {
            var _checkboxs = $(this.element).find(".d-list-item-checkbox"), self = this,
            _val = $(this.element).children(".d-listbox-values"), _selValues = new Array();

            _checkboxs.each(function (i, n) {
                var _checkbox = $(n);
                if (_checkbox.attr("checked")) {
                    var $item = _checkbox.closest(".d-list-item"),
                     _v = $item.find(self.options.dataValueField);
                    if (_v.length) {
                        if (_v.get(0).tagName == "INPUT")
                            _selValues.push(_v.val());
                        else
                            _selValues.push(_v.text());
                    }
                }
            });

            if (_selValues.length)
                _val.val(_selValues.join(","));
            else
                _val.val("");
        },
        getSelected: function () {
        },
        add: function (content) {
            var _content = content,
            $tmp = $(content);

            if ($tmp.length) {
                if ($tmp.get(0) == "LI")
                    _content = $tmp.html();
            }

            var $li = $("<li/>").html(_content)
                        .appendTo($(".d-list-items-holder", this.element));
            this._initItem($li);
        },
        del: function ($li) {
        },
        _showLoader: function () {
            var _loader = $("<div/>").addClass("d-loader").appendTo(this.element), el = this.element;
            _loader.css({
                height: el.height() + "px",
                width: el.width() + "px",
                "left": el.position().left + "px",
                "top": el.position().top + "px"
            });
            return _loader;
        },
        _hideLoader: function () {
            var loader = $(".d-loader", this.element);
            if (loader.length) loader.remove();
        },
        load: function (_url, _routeData, _replaceExists, httpMethod) {
            var self = this, el = this.element;
            $.ajax({
                type: httpMethod ? httpMethod : "POST",
                url: _url,
                data: _routeData,
                beforeSend: function () {
                    self._showLoader();
                },
                success: function (data) {
                    if (data) {
                        var $d = $(data);
                        if ($d.length()) {

                            if (_replaceExists) {
                                if ($d.get(0).tagName == "UL")
                                    el.empty();
                                $d.appendTo(el);
                                self._initDataContainer($d);
                            }
                            else {
                                var $items = null,
                                 $ul = el.children("d-list-items-holder");
                                if ($d.get(0).tagName == "UL")
                                    $items = $(">li", $d);
                                else
                                    $items = $d;
                                $ul.append($d);
                                $items.each(function (i, n) {
                                    self._initItem($(n));
                                });
                            }
                        }

                        if (self.options.inline) {
                            var _items = el.children("ul").find(".d-list-item:visible"), _w = 0;
                            _items.each(function (i, n) {
                                _w += $(n).outerWidth(true);
                            });

                            if (_w) {
                                el.children("ul").width(_w);
                                el.css({ "overflow-y": "hidden" });
                            }
                        }

                    }
                    self._triggerEvent("itemsloaded", self);
                    self._hideLoader();
                }
            });
        },
        loadData: function (_url, _routeData) {
            $ul = $(">.d-list-items-holder", this.element);
            $ul.empty();
            this.loadJson(_url, _routeData, this.element.attr("id") + "_tmpl");
        },
        loadJson: function (_url, _routeData, tmplID, callBack, httpMethod) {
            var self = this;
            $.ajax({
                type: httpMethod ? httpMethod : "POST",
                url: _url,
                dataType: "json",
                data: _routeData,
                beforeSend: function () {
                    self._showLoader();
                },
                success: function (data) {
                    self.dataBind(data.Model, tmplID);
                    self._triggerEvent("itemsloaded", self);
                    self._hideLoader();
                    if ($.isFunction(callBack)) callBack(self, data);
                }
            });
        },
        dataBind: function (data, tmplID) {
            var self = this;
            if ((data) && (data.length) && (tmplID) && ($.tmpl)) {
                $ul = $(">.d-list-items-holder", self.element);
                var __tmpl = $("#" + tmplID);
                if (__tmpl.length == 0) return;
                __tmpl.tmpl(data).appendTo($ul);

                var $items = $("li:not(.d-list-item)", $ul);
                $items.each(function (i, n) {
                    self._initItem($(n));
                });

                if (self.options.inline) {
                    var _items = $ul.find(".d-list-item:visible"), _w = 0;
                    _items.each(function (i, n) {
                        _w += $(n).outerWidth(true);
                    });
                    if (_w) {
                        $ul.width(_w);
                        self.element.css({ "overflow-y": "hidden" });
                    }
                }
            }
        },
        select: function (_val) {
            var $items = $(">.d-list-items-holder>.d-list-item", this.element).find(this.options.dataValueField);
            $items.each(function (i, n) {
                if ($(n).val() == _val) {
                    $(n).click();
                    return false;
                }
            });
        },
        destroy: function () {
            $.Widget.prototype.destroy.call(this);
        }
    });

    $.widget("ui.dnamenu", {
        options: {
            type: "horizontal", //horizontal  vertical
            topMenuClass: null,
            topItemClass: null,
            topItemHoverClass: null, // "ui-state-active",
            topItemSelectedClass: null, // "ui-state-active",
            subMenuClass: null, //"ui-widget-content",
            subMenuItemClass: null, // "ui-state-default",
            subMenuItemHoverClass: null, // "ui-state-active",
            open: null,
            close: null,
            itemClick: null,
            skateBoard: false,
            skateBoardClass: "ui-state-highlight",
            showEffect: "slide", //'blind', 'clip', 'drop', 'explode', 'fold', 'puff', 'slide', 'scale', 'size', 'pulsate'
            hideEffect: "slide", //'blind', 'clip', 'drop', 'explode', 'fold', 'puff', 'slide', 'scale', 'size', 'pulsate'
            contextElement: null,
            delay: 100,
            opacity: 1
        },
        _create: function () {
            var self = this, opts = this.options, el = this.element, eventPrefix = this.widgetEventPrefix,
            _topItems = $(">ul>.d-menu-item", el);
            el.addClass("d-menu");

            if ($.fn.bgiframe)
                el.bgiframe();

            if (opts.open)
                el.bind(eventPrefix + "open", opts.open);

            if (opts.close)
                el.bind(eventPrefix + "close", opts.close);

            if (opts.itemClick)
                el.bind(eventPrefix + "itemclick", opts.itemClick);

            if (_topItems.length) {
                _topItems.addClass("d-top-menu-item");
                if (opts.topItemClass) _topItems.addClass(opts.topItemClass);

                //_topItems.each(function (i, n) { $(n).data("top", true); });

                if (opts.type == "horizontal") {
                    //_topItems.css({ "float": "left" });
                    $(">ul", el).addClass("d-horizontal");
                }
                else {
                    $(">ul", el).addClass("ui-helper-reset d-vertical");
                    if (opts.type == "context")
                        el.addClass("d-context-menu");
                }

                _topItems.css({
                    "position": "relative"
                });
            }

            var _allItems = $(".d-menu-item:not(.d-state-disabled)", el);
            $(document).click(self._delegate(self, self._ondocumentclick));

            if (_allItems.length) {
                _allItems.live("mouseenter", self._delegate(self, self._onmouseenter))
                             .live("mouseleave", self._delegate(self, self._onmouseleave))
                             .live("click", self._delegate(self, self._onitemclick));
                //.addClass("ui-helper-reset");.live("click", function () { el.trigger(eventPrefix + "click", this); })

                if (opts.subMenuItemClass) {
                    _allItems.each(function (i, n) {
                        $(n).find(".d-menu-item").addClass(opts.subMenuItemClass);
                    });
                }

                var $ul = $(".d-menu-container", _allItems);

                if ($ul.length) {
                    $ul.each(function (i, n) {
                        var _c = $(n);
                        _c.css({
                            "width": _c.outerWidth(true) + "px"
                        });
                    });
                    $ul.hide();
                }

                if ((opts.skateBoard) && (opts.type == "horizontal")) {
                    this.skated = $("<li />").addClass("d-menu-skateitem")
                                                            .appendTo($(">ul", el))
                                                            .css({ position: "absolute" });
                    if (opts.skateBoardClass)
                        this.skated.addClass(opts.skateBoardClass);
                    var $fixedEl = el.children(".d-state-selected").length ? el.children(".d-state-selected") : $(_topItems[0]);
                    if ($fixedEl.length)
                        this._fixedTo($fixedEl);
                }
            }
            if (opts.type == "context")
                el.hide();
        },
        dropdown: function (element) {
            if (element) {
                var $el = $(element),
                x = ($el.position().left + $el.outerWidth(true)) - this.element.outerWidth(true),
                y = $el.position().top + $el.outerHeight(true);
                this.showMenu(x > 0 ? x : 0, y > 0 ? y : 0);
            }
        },
        closeMenu: function () {
            var self = this;
            if (!this.element.hasClass("d-state-open")) return;
            clearTimeout(this.element.data("contextTimer"));
            this.element.data("contextTimer", setTimeout(function () {
                self.element.removeClass("d-state-open");
                self.element.hide(self.options.hideEffect, { direction: "up" }, self.options.delay);
            }, 100));
        },
        showMenu: function (x, y) {
            var self = this;
            if (this.element.hasClass("d-state-open"))
                this.closeMenu();

            clearTimeout(this.element.data("contextTimer"));
            this.element.data("contextTimer", setTimeout(function () {
                self.element.css({
                    left: x + "px",
                    top: y + "px"
                });
                self.element.show(self.options.showEffect, { direction: "up" }, self.options.delay);
                self.element.addClass("d-state-open");
            }, 100));
        },
        _triggerEvent: function (eventName, eventArgs) {
            this.element.trigger(this.widgetEventPrefix + eventName, eventArgs);
        },
        _delegate: function (context, handler) {
            return function (e) {
                handler.apply(context, [e, this]);
            };
        },
        _onitemclick: function (e, element) {
            e.stopPropagation();
            if (this.element.hasClass("d-context-menu"))
                this.closeMenu();

            this._triggerEvent("itemclick", element);
        },
        _ondocumentclick: function (e, element) {
            var self = this;
            try {
                if (this.element.hasClass("d-context-menu")) {
                    if (this.element.hasClass("d-state-open"))
                        this.closeMenu();
                }

                if (self._contains(this.element, e.target))
                    return;

                $(this.element).children(".d-menu-item").each(function (i, item) {
                    //if ($(item).data("open"))
                    if ($(item).hasClass("d-state-open"))
                        self.close($(item));
                });
            }
            catch (e) {
                return;
            }
        },
        _fixedTo: function (element) {
            if (this.skated && element.parent().hasClass("d-horizontal")) {
                var _l = element.position().left, _w = element.outerWidth(false) - 2;
                this.skated.css({
                    left: _l,
                    width: _w
                })
                .data("origLeft", _l)
                .data("origWidth", _w);
            }
        },
        _parkTo: function (element) {
            if (this.skated && element.parent().hasClass("d-horizontal")) {
                this.skated.stop().animate({
                    left: this.skated.data("origLeft"),
                    width: this.skated.data("origWidth")
                });
            }
        },
        _slideTo: function (element) {
            if (this.skated && element.parent().hasClass("d-horizontal")) {
                this.skated.stop().animate({
                    left: element.position().left,
                    width: element.outerWidth(false) - 2
                });
            }
        },
        _onmouseenter: function (e, element) {
            var $li = $(element), opts = this.options;

            if ($li.hasClass("d-state-disabled")) return;

            if (opts.skateBoard) this._slideTo($li);

            if ($li.hasClass("d-state-open")) return;
            // if ($li.data("open")) return;

            // if ($li.data("top"))
            if ($li.hasClass("d-top-menu-item"))
                $li.addClass(opts.topItemHoverClass);
            else
                $li.addClass(opts.subMenuItemHoverClass);

            if (!this._contains(element, e.relatedTarget)) {
                this._triggerEvent("open", $li);
                //$li.data("open", true);
                $li.addClass("d-state-open");
                this.open($li);

                var parentItem = $li.parent().closest(".d-menu-item")[0];
                if (parentItem && !$.contains(parentItem, e.relatedTarget))
                    this._onmouseenter(e, parentItem);
            }
        },
        _onmouseleave: function (e, element) {
            var $li = $(element), opts = this.options;
            //if (!$li.data("open")) return;
            if (!$li.hasClass("d-state-open")) return;

            if (opts.skateBoard) this._parkTo($li);

            //if ($li.data("top"))
            if ($li.hasClass("d-top-menu-item"))
                $li.removeClass(opts.topItemHoverClass);
            else
                $li.removeClass(opts.subMenuItemHoverClass);

            if (!this._contains(element, e.relatedTarget)) {
                this._triggerEvent("close", $li);
                //$li.data("open", false);
                $li.removeClass("d-state-open");
                this.close($li);

                var parentItem = $li.parent().closest(".d-menu-item")[0];
                if (parentItem && !$.contains(parentItem, e.relatedTarget))
                    this._onmouseleave(e, parentItem);
            }
        },
        _getDirectionOptions: function ($li) {
            var parent = $li.parent();
            return {
                direction: parent.hasClass("d-horizontal") ? "up" : "left"
            };
        },
        _contains: function (parent, child) {
            try {
                return $.contains(parent, child);
            } catch (e) {
                return false;
            }
        },
        _setMenuPosition: function ($li, target) {
            var parent = $li.parent();

            $(target).css({
                "position": "absolute",
                "left": 0 + "px",
                "z-index": 2000
            });

            tw = $(target).width(), sw = window.innerWidth, lpos = $li.position().left, lw = $li.outerWidth(true), cl = 0;
            cl = ((tw + lpos) > sw ? -(tw - lw) : 0);
            if (cl) $(target.css({ "left": cl + "px" }));

            if (!parent.hasClass("d-horizontal")) {
                $(target).css({
                    "top": "0px",
                    "left": $li.outerWidth() + "px",
                    "z-index": "5000"
                });
            }
        },
        _wrap: function (element) {
            if (!element.parent().hasClass('d-group-helper')) {
                element.show();
                var _w = element.outerWidth() + 5,
                _h = element.outerHeight();
                element.parent().css("position", "relative");
                element.wrap(
                             $('<div/>')
                             .addClass('d-group-helper')
                             .css({
                                 width: _w,
                                 height: _h
                             }));
            }
            return element.parent().css({ opacity: this.options.opacity });
        },
        open: function ($li) {
            var self = this;
            $($li).each(function (i, n) {
                var $item = $(n);
                clearTimeout($item.data("timer"));
                $item.data("timer", setTimeout(function () {
                    var $ul = $item.find(".d-menu-container:first");
                    if ($ul.length) {
                        var wrapper = self._wrap($ul);
                        self._setMenuPosition($item, wrapper);
                        wrapper.show(self.options.showEffect, self._getDirectionOptions($item), self.options.delay);
                    }
                }), 100);
            });
        },
        close: function ($li) {
            var self = this;
            $($li).each(function (i, n) {
                var $item = $(n);
                clearTimeout($item.data("timer"));
                $item.data("timer", setTimeout(function () {
                    var $ul = $item.find(".d-menu-container:first");
                    if ($ul.length) {

                        self._wrap($ul).hide(self.options.hideEffect, self._getDirectionOptions($item), self.options.delay);
                    }
                    $ul.find("ul").stop(false, true);
                }, 100));
            });
        },
        addItems: function () { },
        addItem: function (oParent, oItem) {
            var _parent = this._checkParent(oParent),
             _dom = $("<li/>").appendTo(_parent)
            $("<a/>").appendTo(_dom)
                                .attr("href", oItem.url ? oItem.url : "#")
                                .text(oItem.text ? oItem.text : "");
        },
        destroy: function () {
            this.element.unbind();
            $("li", this.element).unbind();
            $.Widget.prototype.destroy.call(this);
        }
    });

    $.widget("ui.pager", {
        options: {
            totalpages: 50,
            totalrecords: 0,
            pageindex: 1,
            pagesize: 20,
            changed: null
        },
        _create: function () {
            var self = this, opts = this.options, el = this.element, eventPrefix = this.widgetEventPrefix;
            el.css({ height: 25 });

            opts.totalpages = parseInt(opts.totalrecords / opts.pagesize) + (opts.totalpages % opts.pagesize ? 1 : 0);
            if ($.isFunction(opts.changed)) {
                el.bind(eventPrefix + "changed", opts.changed);
            }

            var $summary = $("<span/>").addClass("d-pager-summary").appendTo(el);
            $summary.css({ "float": "right" }).text(self._format("Page {0} of {1} ({2} items)", opts.pageindex, opts.totalpages ? opts.totalpages : 1, opts.totalrecords));

            if (opts.totalpages == 0) return;

            var $ul = $("<ul/>").appendTo(el)
                                          .addClass("ui-helper-reset"),

            $first = $("<li/>").appendTo($ul)
                                       .addClass("ui-pager-first")
                                       .append($("<span/>").addClass("ui-icon ui-icon-triangle-1-w")),

            $prev = $("<li/>").appendTo($ul)
                                       .addClass("ui-pager-prev")
                                       .append($("<span/>").addClass("ui-icon ui-icon-carat-1-w")),

            $last = $("<li/>").addClass("ui-pager-last")
                                      .append($("<span/>").addClass("ui-icon ui-icon-triangle-1-e")),

            $next = $("<li/>").addClass("ui-pager-next")
                                       .append($("<span/>").addClass("ui-icon ui-icon-carat-1-e"));


            $first.bind("click", function () {
                self.go(1, $(this));
                $first.hide();
                $prev.hide();
                $last.show();
                $next.show();
            });

            $prev.bind("click", function () {
                self.go(opts.pageindex - 1, $(this));
                if (opts.pageindex == 1) {
                    $first.hide();
                    $prev.hide();
                    $last.show();
                    $next.show();
                }
                else {
                    $last.show();
                    $next.show();
                }
            });

            if (opts.pageindex == 1) { // no forward
                $first.hide();
                $prev.hide();
            }

            var _range = this._updateRange();

            //PageNums
            for (i = _range[0]; i <= _range[1]; i++) {
                var $num = $("<li>" + i.toString() + "</li>").appendTo($ul)
                                                                               .addClass("ui-page-num")
                                                                               .attr("index", i);
                //currentpage is do nothing
                if (opts.pageindex == i)
                    $num.addClass("ui-state-active");
                $num.bind("click", function () {
                    self.go(parseInt($(this).attr("index")), $(this));
                });
            }

            $ul.append($next);
            $ul.append($last);

            //Move next//Move last

            $last.bind("click", function () {
                self.go(opts.totalpages, $(this));
                $first.show();
                $prev.show();
                $last.hide();
                $next.hide();
            });
            $next.bind("click", function () {
                self.go(opts.pageindex + 1, $(this));
                if (opts.pageindex == opts.totalpages) {
                    $first.show();
                    $prev.show();
                    $last.hide();
                    $next.hide();
                }
                else {
                    $prev.show();
                    $first.show();
                }
            });

            if (opts.pageindex == opts.totalpages) {
                $last.hide();
                $next.hide();
            }

            var _btns = $(">li", $ul);
            _btns.each(function () {
                var _btn = $(this);
                _btn.addClass("ui-state-default")
                      .css({
                          "float": "left",
                          width: 16,
                          cursor: "pointer",
                          margin: "1px",
                          padding: "3px",
                          "text-align": "center"
                      });
                _btn.hover(function () { $(this).addClass("ui-state-hover"); }, function () { $(this).removeClass("ui-state-hover"); });
            });
        },
        _format: function () {
            if (arguments.length == 0)
                return null;

            var str = arguments[0];
            for (var i = 1; i < arguments.length; i++) {
                var re = new RegExp('\\{' + (i - 1) + '\\}', 'gm');
                str = str.replace(re, arguments[i]);
            }
            return str;
        },
        _updateRange: function () {
            var opts = this.options, startAt = 1, end = 11;

            while (opts.pageindex >= end) {
                startAt = startAt + 10;
                end = end + 10;
            }

            if (end > opts.totalpages)
                end = opts.totalpages;

            this.range = [startAt, end];
            return this.range;
        },
        destroy: function () {
            this.element.unbind();
            $("ul>li", this.element).unbind();
            $.Widget.prototype.destroy.call(this);
        },
        reset: function (_total) {
            var opts = this.options;
            opts.pageindex = 1;
            opts.totalrecords = _total;
            this.element.empty();
            this._create();
        },
        _refresh: function () {
            var _range = this._updateRange(), opts = this.options,
            _nums = $(".ui-page-num", this.element);
            _nums.removeClass("ui-state-active");
            _nums.each(function (i, n) {
                _index = i + _range[0];
                if (_index > opts.totalpages) {
                    $(this).hide();
                }
                else {
                    $(this).attr("index", _index)
                             .show()
                             .text(_index);
                    if (_index == opts.pageindex)
                        $(this).addClass("ui-state-active");
                }
            });
        },
        reload: function () {
            this.element.trigger(this.widgetEventPrefix + "changed", { pageIndex: this.options.pageindex, pageSize: this.options.pagesize });
        },
        go: function (_index, _btn) {
            var opts = this.options, self = this, el = this.element, eventPrefix = this.widgetEventPrefix;
            opts.pageindex = _index;
            //el.trigger(eventPrefix + "changed", { pageIndex: _index, pageSize: opts.pagesize });
            el.trigger(eventPrefix + "changed", { pageIndex: _index, pageSize: opts.pagesize });
            if (_btn.hasClass("ui-page-num")) {
                $("li", el).removeClass("ui-state-active");
                _btn.addClass("ui-state-active");
            } else {
                // go next or last
                if (_index > this.range[1]) {
                }
                this._refresh();
            }
        }
    });

    $.widget("ui.rating", {
        options: {
            value: 0,
            maxrating: 5,
            readOnly: false,
            starIcon: "ui-icon ui-icon-star",
            cssClass: "ui-state-default",
            hoverClass: "ui-state-active",
            change: null
        },
        _create: function () {
            var self = this, opts = this.options, el = this.element;
            if (opts.change)
                this.element.bind("ratingchange", opts.change);

            _starts = $("<ul></ul>").appendTo(el)
                                               .addClass("ui-helper-reset");
            //.css({ "display": "inline-block" });
            if (!opts.readOnly) {
                _starts.bind("mouseenter", function () {
                    self.mouseOn = true;
                });
                _starts.bind("mouseleave", function () {
                    self._setRatings(opts.value);
                    self.mouseOn = false;
                });
            }

            for (var i = 1; i < opts.maxrating + 1; i++) {
                _start = $("<li></li>").appendTo(_starts)
                                   .addClass(opts.cssClass)
                                   .css({
                                       "float": "left",
                                       "border": "none",
                                       "background": "none",
                                       "cursor": "pointer"
                                   })
                                   .attr("title", i)
                                   .append($("<span></span>").addClass(opts.starIcon));

                if (!opts.readOnly) {
                    _start.hover(function () {
                        //$(this).addClass(opts.hoverClass);
                        self._setRatings(parseInt($(this).attr("title")));
                    },
                function () {
                    if (!self.mouseOn)
                        $(this).removeClass(opts.hoverClass);
                });

                    _start.bind("click", function () {
                        opts.value = parseInt($(this).attr("title"));
                        el.trigger("ratingchange", opts.value);
                    });
                }
            }
            self._setRatings(opts.value);
        },
        _setRatings: function (_value) {
            var opts = this.options, _starts = $("li", this.element);
            _starts.removeClass(opts.hoverClass);
            _starts.each(function (i, n) {
                var _start = $(this), _rating = parseInt(_start.attr("title"));
                if (_rating <= _value)
                    _start.addClass(opts.hoverClass);
            });
        },
        setValue: function (_value) {
            this._setRatings(_value);
        },
        destroy: function () {
            $("li", this.element).unbind();
            $(">ul", this.element).unbind().remove();
            $.Widget.prototype.destroy.call(this);
        }
    });
    domParser = function (element) {
        this.element = $(element);
    }

    domParser.prototype = {
        isBold: function () { return (this.isIn("strong") || this.isIn("b") || this.hasStyle("font-weight", "bold")) ? true : false; },
        isItalic: function () { return (this.isIn("i") || this.hasStyle("font-style", "italic")) ? true : false; },
        isUnderline: function () { return (this.isIn("u") || this.hasStyle("text-decoration", "underline")) ? true : false; },
        isOverline: function () { return (this.hasStyle("text-decoration", "overline")) ? true : false; },
        isLineThrough: function () { return (this.hasStyle("text-decoration", "line-through")) ? true : false; },
        isLink: function () { return (this.isTag("A") || this.isIn("a")) ? true : false; },
        isJustifyLeft: function () { return (this.hasStyle("text-align", "left")) ? true : false; },
        isJustifyCenter: function () { return (this.isIn("center") || this.hasStyle("text-align", "center")) ? true : false; },
        isJustifyRight: function () { return (this.hasStyle("text-align", "right")) ? true : false; },
        isJustifyNone: function () { return (!this.isJustifyCenter() && !this.isJustifyLeft() && !this.isJustifyRight()) ? true : false; },
        isOrderList: function () { return this.isIn("ol") ? true : false; },
        isUnorderList: function () { return this.isIn("ul") ? true : false; },
        isSub: function () { return this.isIn("sub") ? true : false; },
        isSup: function () { return this.isIn("sup") ? true : false; },
        getFontFarmily: function () { return this.element.css("font-family") ? this.element.css("font-family") : "inherit"; },
        getForeColor: function () { return this.element.css("color") ? this.element.css("color") : "inherit"; },
        getBackgroundColor: function () { return this.element.css("background-color") ? this.element.css("background-color") : "inherit"; },
        getFontSize: function () { return this.element.css("font-size") ? this.element.css("font-size") : "inherit"; },
        isTag: function (_tagName) { return this.getTagName() == _tagName ? true : false; },
        isIn: function (_tagName) { return this.element.closest(_tagName).length ? true : false; },
        hasStyle: function (_name, _value) {
            if (this.element.css(_name)) {
                return this.element.css(_name).toString().toLocaleLowerCase().indexOf(_value) > -1;
            }
            else
                return false;
        },
        getTagName: function () { return this.element[0].tagName; }
    };

    $.widget("ui.richtextbox", {
        options: {
            mode: "editor",
            width: "auto",
            height: 300,
            bgColor: "white",
            border: 0,
            textFontSize: "12",
            textBGColor: "white",
            textFont: "Verdana, Arial, Helvetica",
            documentStyle: false,
            normalized: null,
            autoEncode: false
        },
        _create: function () {
            var self = this, opts = this.options, eventPrefix = this.widgetEventPrefix, el = this.element;


            self.buildEditor();
            self.initEditor(this.getText());
            self.toggleMode(opts.mode);
            if (opts.normalized)
                el.bind(eventPrefix + "normalized", opts.normalized);
        },
        _triggerEvent: function (eventName, eventArgs) {
            this.element.trigger(this.widgetEventPrefix + eventName, eventArgs);
        },
        destroy: function () {
            $.Widget.prototype.destroy.call(this);
        },
        widget: function () {
            return this.rteContainer;
        },
        syncContent: function (mode) {
            if (mode == 'editor') {
                //var c = this.getText();
                this.setHtml(this.getText());
                //alert(this.element.val());
            }
            else {
                var content = this.getHtml();
                this.setText(content);
            }
        },
        getHtml: function () {
            if (this.editor.document)
                return this.editor.document.body.innerHTML;
            else {
                this.initEditor(this.getText());
                return this.element.val();
            }
        },
        active: function () {
            if (this.editor.document == undefined || this.editor.document == null)
                this.initEditor(this.getText());
            this.editor.focus();
        },
        setHtml: function (content) {
            this.editor.document.body.innerHTML = content;
        },
        setText: function (content) {
            this.isIE() ? this.element.val(content) : this.element.val(content);
        },
        getText: function () {
            return this.isIE() ? this.element.val() : this.element.val();
        },
        execCmd: function (command, option) {
            if (this.editor) {
                if (option == 'removeFormat') {
                    command = option;
                    option = null;
                }
                try {
                    //fix the selection lost issuse
                    if (this.isIE() && this.curSelection)
                        this.curSelection.select();
                    this.editor.document.execCommand(command, false, option);
                }
                catch (e) {
                    alert(command + ": not supported");
                }
                this.editor.focus();
            }
        },
        fixIEBreak: function () {
            var self = this;
            if (this.isIE()) {
                var _doc = $(this.editor.document);

                //fix the ie will auto lose the focus that could not executeCommand
                _doc.bind("mouseup", function () {
                    if (self.isIE()) {
                        if (self.editor.document.selection)
                            self.curSelection = self.editor.document.selection.createRange();
                        else
                            self.curSelection = 0;
                    }
                });

                //fix the ie auto generate the p tag as break 
                _doc.bind("keyup", function (event) {
                    if (event.keyCode == 13) {
                        var formmated = self.getHtml().replace(/<P>&nbsp;<\/P>/ig, "")
                                                                                      .replace(/<P>/ig, "")
                                                                                      .replace(/<\/P>/ig, "<br/>");
                        self.setHtml(formmated);
                    }
                });
            }
        },
        setBold: function () { this.runCmd("Bold"); },
        setItalic: function () { this.runCmd("Italic"); },
        setUnderline: function () { this.runCmd("Underline"); },
        setStrikeThrough: function () { this.runCmd("StrikeThrough"); },
        setJustifyLeft: function () { this.runCmd("JustifyLeft"); },
        setJustifyCenter: function () { this.runCmd("JustifyCenter"); },
        setJustifyRight: function () { this.runCmd("JustifyRight"); },
        setJustifyFull: function () { this.runCmd("Justifyfull"); },
        setFontName: function (_name) { this.runCmd("fontName", _name); },
        setFontSize: function (_size) { this.runCmd("fontSize", _size) },
        insertOrderedList: function () { this.runCmd("InsertOrderedList"); },
        insertUnorderedList: function () { this.runCmd("InsertUnorderedList"); },
        setIndent: function () { this.runCmd("Indent"); },
        setOutdent: function () { this.runCmd("Outdent"); },
        setForeColor: function (_color) { this.runCmd("forecolor", _color); },
        setBackgroundColor: function (_color) { this.runCmd("hilitecolor", _color); },

        setSuperscript: function () { this.runCmd("Superscript"); },
        setSubscript: function () { this.runCmd("Subscript"); },
        insertHorizontalRule: function () { this.runCmd("InsertHorizontalRule"); },
        insertParagraph: function () { this.runCmd("InsertParagraph"); },
        insertDate: function () { this.runCmd("insertHTML", "<span>" + (new Date()).toDateString() + "</span>"); },
        insertTime: function () { this.runCmd("insertHTML", "<span>" + (new Date()).toLocaleTimeString() + "</span>"); },

        unlink: function () { this.runCmd("Unlink"); },
        removeFormat: function () { this.runCmd("RemoveFormat"); },
        copy: function () { this.runCmd("Copy"); },
        cut: function () { this.runCmd("Cut"); },
        paste: function () { this.runCmd("Paste"); },
        print: function () { this.runCmd("Print"); },
        runCmd: function (cmd, opt) {
            if (this.isIE() && !this.curSelection) {
                this.editor.focus();
                this.curSelection = this.editor.document.selection.createRange();
            }
            if (cmd && opt) {
                if (cmd == 'insertHTML' && this.isIE()) this.curSelection.pasteHTML(opt);
                else this.execCmd(cmd, opt);
            }
            else if (cmd) this.execCmd(cmd);
            if (this.isIE()) this.curSelection = 0;
        },
        toggleview: function () {
            if (this.curMode == "source")
                this.toggleMode("editor");
            else
                this.toggleMode("source");
            //this.resize();
        },
        toggleMode: function (mode) {
            var el = this.element;
            if (mode == "source") {
                //disable the toolbar
                $(this.rteiFrame).hide();
                el.show().focus();
            }
            else {
                el.hide();
                $(this.rteiFrame).show();
                this.editor.focus();
            }
            this.syncContent(mode);
            this.curMode = mode;
        },
        resize: function () {
            var el = this.element, _parent = el.parent(),
            _w = _parent.width() ? _parent.width() + "px" : "100%",
            _h = _parent.height() ? _parent.height() + "px" : "100%";

            $(this.rteiFrame).css({
                height: _h,
                width: _w
            });

            el.css({
                height: _h,
                width: _w
            });
        },
        buildEditor: function () {
            var self = this, opts = this.options, el = this.element,
            rteContainer = el.parent();
            var _strFrame = "<iframe src='javascript:void(0);' frameborder='0' style='width:100%;'></iframe>";
            rteContainer.css({ "background-color": opts.bgColor })
                               .html(_strFrame);
            el.appendTo(rteContainer);
            el.css({
                "background-color": opts.textBGColor,
                "border": opts.border
            });

            //            if (self.isIE()) {
            //                var ieW = (opts.width == "auto" || opts.width == "100%") ? "100%" : (opts.width + 3) + "px";
            //                el.css({
            //                    "overflow": "auto",
            //                    width: ieW
            //                });
            //            }

            this.rteiFrame = $("iframe", rteContainer)[0];
            this.rteContainer = rteContainer;
            this.resize();
        },
        getRTE: function () {
            return this;
        },
        getEditor: function () {
            var e = false;
            if (this.isGecko()) e = this.rteiFrame.contentWindow;
            else if (this.isIE()) e = this.rteiFrame.contentWindow;

            if (e && !this.isDesignModeSupported()) e = false;
            return e;
        },
        increaseHeight: function () {
            this._setHeight(this.element.height() + 100);
        },
        reduceHeight: function () {
            if (this.element.height() > 120)
                this._setHeight(this.element.height() - 100);
        },
        _setHeight: function (_height) {
            $(this.rteiFrame).css("height", _height ? _height : "100%");
            this.element.css("height", _height ? _height : "100%");
        },
        isDesignModeSupported: function () {
            return (document.designMode && document.execCommand) ? true : false;
        },
        isGecko: function () { return (navigator.userAgent.indexOf('Gecko') != -1) ? true : false; },
        isIE: function () { return $.browser.msie; },
        initEditor: function (content) {
            var self = this, opts = this.options, el = this.element;
            if (this.editor = this.getEditor()) {
                var _styles = '<style> ' +
                                     'BODY { ' +
                                     'margin: 4px; ' +
                                     'background-color: ' + opts.textBGColor + '; ' +
                                     '} ' +
                                     'BODY, TD, TH { ' +
                                     'color: black; ' +
                                     'font-family: ' + opts.textFont + '; ' +
                                     'font-size: ' + opts.textFontSize + 'px; ' +
                                     '} ' +
                                     'TD { border: 1px dashed silver; } ' +
                                     'P { margin: 0px; } ' +
                                     '</style>';
                if (this.options.documentStyle) {
                    _styles = "";

                    $.each(document.styleSheets, function (i, n) {
                        _styles += '<link href="' + n.href + '" type="text/css" rel="stylesheet">';
                    });
                }

                var html = '<html><head>' + _styles + '</head>' +
                                     '<body style="background:none;">' +
                                     content.replace(/<STYLE>[^<]+<\/STYLE>(\r?\n)*/gi, '') +
                                     '</body></html>';
                this.editor.document.designMode = 'on';
                //if (self.isGecko()) this.editor.document.execCommand('useCSS', false, true);
                this.editor.document.open();
                this.editor.document.write(html);
                this.editor.document.close();
                if (this.setFocus) this.editor.focus();

                //$(this.rteiFrame.contentWindow).bind("pageshow", function () { alert("show") });

                var _normalizedHandler = function (event) {
                    if (event.target) {
                        var _parser = new domParser(event.target);
                        self._triggerEvent("normalized", _parser);
                    }
                };


                $(this.editor.document).bind("mousedown", _normalizedHandler);
                //.bind("load", function () { alert("load"); });

                // .bind("keypress",_normalizedHandler);

                var _form = el.closest("form");
                if (_form.length) {
                    _form.bind("submit", function () {
                        //encoded the html before submit
                        //self.setText(self.getHtml());
                        if (self.curMode == "editor")
                            self.syncContent("source");
                        if (opts.autoEncode) {
                            self.isIE() ? el.val(self.htmlEncode(self.getHtml())) : el.text(self.htmlEncode(self.getHtml()));
                        }
                    });
                }

                this.fixIEBreak();
            }
            else alert("Sorry, your browser doesn't support richtext editing!");
        },

        encodedHtml: function () {
            var self = this;
            if (self.curMode == "editor")
                self.syncContent("source");
            return self.htmlEncode(self.getText());
        },
        isHtmlEncode: function (strHtml) {
            if (strHtml.search(/&amp;/g) != -1 || strHtml.search(/&lt;/g) != -1 || strHtml.search(/&gt;/g) != -1)
                return true;
            else
                return false;
        },
        htmlEncode: function (strHtml) {
            if (strHtml)
                return strHtml.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
            else
                return "";
        },
        htmlDecode: function (strHtml) {
            if (this.isHtmlEncode(strHtml))
                return strHtml.replace(/&amp;/g, '&').replace(/&lt;/g, '<').replace(/&gt;/g, '>');
            return strHtml;
        },
        insertLink: function (_url, _target) {
            if (_url && _url != 'http://') {
                if (this.curSelection)
                    this.runCmd('insertHTML', '<a href="' + _url + '" target="' + _target + '">' + this.curSelection.text);
                else this.runCmd('createLink', _url);
            }
        },
        formatBlock: function (_tag) {
            if (_tag) {
                this.runCmd("formatBlock", "<" + _tag + ">");
            }
        },
        insertImage: function (_url) {
            if (_url && _url != 'http://') {
                if (this.curSelection) this.runCmd('insertHTML', '<IMG src="' + _url + '">');
                else this.runCmd('insertImage', _url);
            }
        }
    });
    $.widget("ui.tags", {
        options:
        {
            event: "click",
            pos: "left",
            selectedIndex: 0,
            select: null,
            show: null
        },
        _create: function () {
            var self = this, opts = this.options, el = this.element, layout = opts.pos, _parent = el.parent(),
            // h = _parent.height() - parseInt(_parent.css("padding-top")) - parseInt(_parent.css("padding-bottom")) - 2;
             _table = $("<table></table>").appendTo(el)
                                                                .attr("cellpadding", "0")
                                                                .attr("cellspacing", "0")
                                                                .css({ "width": "100%" }),

            _tr = $("<tr></tr>").appendTo(_table),

            _leftCol = $("<td></td>").appendTo(_tr)
                                                     .attr("valign", "top"),

            _rightCol = $("<td></td>").appendTo(_tr)
                                                       .attr("valign", "top");

            if ((layout != "left") && (layout != "right"))
                layout = "left";

            el.addClass("ui-corner-all ui-widget-header")
              .css({
                  "padding": "5px",
                  "background-position": "0 0"
              });


            if (opts.select)
                el.bind("tagselect", opts.select);
            if (opts.show)
                el.bind("tagshow", opts.show);

            var ul = el.find("ul:first"),
            _panels = $(">div", el);

            if (ul.length > 0) {
                if (layout == "left") {
                    ul.appendTo(_leftCol);
                    //.css("padding-right", "11px");
                    if (_panels.length) _panels.appendTo(_rightCol);
                    _leftCol.css({
                        "white-space": "nowrap",
                        "width": "80px"
                    });
                }
                else {
                    ul.appendTo(_rightCol);
                    //                    if (layout == "left")
                    //                     ul.css("padding-left", "11px");
                    if (_panels.length) _panels.appendTo(_leftCol);
                    _rightCol.css({
                        "white-space": "nowrap",
                        "width": "80px"
                    });
                }

                ul.addClass("ui-helper-reset")
                   .addClass("ui-tags-nav")
                   .css({ "display": "block" });

                ul.children("li").each(function (i, n) {
                    var $I = $(this);
                    if (layout == "left")
                        $I.addClass("ui-state-default ui-corner-left").css({ "height": "30px", "border-right": "none" });
                    else
                        $I.addClass("ui-state-default ui-corner-right").css({ "height": "30px", "border-left": "none" });

                    $I.hover(function () { $(this).addClass("ui-state-hover"); }, function () { $(this).removeClass("ui-state-hover"); });

                    $I.find("a:first").bind(opts.event, function () {
                        self.selectTag($(this).parent());
                        el.trigger("tagselect", {
                            index: i,
                            tag: $(this).parent(),
                            panel: $($(this).attr("href"))
                        });
                        return false;
                    });

                    if (i == 0)
                        $I.css({ "margin-top": "0px" });
                    else
                        $I.css({ "margin-top": "2px" });

                    if (i == opts.selectedIndex)
                        $I.addClass("ui-state-active").addClass("ui-state-focus")

                    var _link = $("a", this);
                    _link.css({ "display": "inline-block", "padding": "6px" });
                    var _container = $(_link.attr("href"));
                    if (_container.length > 0) {
                        _container.wrap("<div></div>");

                        var _corner = "ui-widget-content ui-corner-left";
                        if (layout == "left")
                            _corner = "ui-widget-content ui-corner-right";

                        _container.addClass(_corner).css({ "padding": "5px" });

                        _container.parent().addClass(_corner)
                        //.addClass("ui-state-active")
                                                   .css({
                                                       "padding": "5px",
                                                       "background-position": "0 0",
                                                       //"width": "100%",
                                                       "display": "none", "overflow": "visible"
                                                   });
                        _container.css({ "overflow": "visible" });

                        if (layout == "left")
                            _container.parent().css({ "border-left": "none" });
                        else
                            _container.parent().css({ "border-right": "none" });

                        if (i == opts.selectedIndex)
                            _container.parent().show();
                    }
                });
            }
        },
        setIndex: function (value) {
            if (this.options.selectedIndex != value) {
                this.selectTag($(">table>tr>td>ul>li", this.element).get(value));
            }
        },
        selectTag: function (el) {
            var self = this, opts = this.options, $tag = $(el), _panel = $($("a", el).attr("href"));

            $(">table>tbody>tr>td>ul>li", self.element).removeClass("ui-state-active")
                                                                     .removeClass("ui-state-focus");

            $(el).addClass("ui-state-active")
                  .addClass("ui-state-focus");

            $(">div", _panel.parent().parent()).hide();
            _panel.parent().show();
            opts.selectedIndex = $(">table>tbody>tr>td>ul>li", self.element).index(el);

            this.element.trigger("tagshow", {
                index: opts.selectedIndex,
                tag: $tag,
                panel: _panel
            });
        },
        remove: function (value) {
            var self = this, opts = this.options, el = this.element, _tag = $(">ul>li", el).get(value),
            _panel = $($("a", _tag).attr("href"));
            $(_tag).unbind();
            $(_tag).remove();
            _panel.remove();
        }
    });

    $.widget("ui.textbox", {
        options:
        {
            value: "",
            clearable: true,
            changed: null,
            waterMark: null,
            waterMarkClass: "",
            width: 200,
            height: 23,
            clearText: "Clear the input text.",
            iconClass: null,
            iconImg: null,
            textClass: null,  //"ui-input ui-state-default",
            activeClass: null, // "ui-state-active",
            cssClass: null, // "ui-textbox ui-corner-all ui-state-default",
            highlightClass: null // "ui-state-highlight"
        },
        _create: function () {
            var self = this, opts = this.options, el = this.element;
            el.wrap("<div></div>");
            var $parent = el.parent();
            $parent.addClass("d-textbox");

            this.container = $parent;
            if (opts.cssClass) $parent.addClass(opts.cssClass);
            if (opts.textClass) el.addClass(opts.textClass);
            if (opts.value) el.val(opts.value);
            if (opts.changed) el.bind("textchange", opts.changed);

            var _offsetWidth = 20;

            //if (opts.clearable)
            // _offsetWidth = 20;

            if ((opts.iconClass) || (opts.iconImg))
                _offsetWidth += 20;

            el.css({ "width": (opts.width - _offsetWidth) + "px" });

            $parent.css({ "width": opts.width + "px" });

            //

            if (opts.iconClass) {
                var _ico = $("<span/>").addClass(opts.iconClass)
                                                    .addClass("d-textbox-icon")
                                                    .prependTo($parent)
                                                    .click(function () { el.focus(); });
                // el.width(el.width() - _ico.width());
                //el.css({ "width": (opts.width-20) + "px" });
            } else {
                if (opts.iconImg) {
                    var _icon = $("<span/>").addClass("d-textbox-icon")
                                                          .css({ "background-image": "url(" + opts.iconImg + ")" })
                                                          .prependTo($parent)
                                                          .click(function () { el.focus(); });
                    //  el.width(el.width() - _icon.width());
                    //el.css({ "width": (opts.width - 20) + "px" });
                }
            }

            if (opts.waterMark)
                el.watermark({
                    waterMark: opts.waterMark,
                    waterMarkClass: opts.waterMarkClass
                });

            if (opts.clearable) {
                var _clr = $("<span/>").addClass("d-textbox-helper");
                if (opts.clearText) {
                    _clr.attr("title", opts.clearText);
                    if ($.fn.tooltip)
                        _clr.tooltip();
                }

                _clr.appendTo($parent);

                //el.width(el.width() - 30);.css({ "float": "right" })

                if (el.val() == "")
                    _clr.hide();

                _clr.bind("click", function () {
                    el.val("");
                    _clr.hide();
                    el.focus();
                });

                el.bind("change", function () {
                    if (el.val() != "")
                        _clr.show();
                    else
                        _clr.hide();
                    opts.value = el.val();
                    el.trigger("textchange", opts.value);
                });
            }

            el.hover(function () {
                $parent.addClass("d-textbox-hover");
                if (opts.highlightClass) $parent.addClass(opts.highlightClass);

            },
             function () {
                 $parent.removeClass("d-textbox-hover");
                 if (opts.highlightClass) $parent.removeClass(opts.highlightClass);

             });

            el.bind("focus", function () {
                $parent.addClass("d-textbox-active");
                if (opts.activeClass) $parent.addClass(opts.activeClass);
            });

            el.bind("blur", function () {
                $parent.removeClass("d-textbox-active");
                if (opts.activeClass) $parent.removeClass(opts.activeClass);
            });
        }
    });

    $.widget("ui.togglePanel", {
        options: {
            showEffect: "slide",
            hideEffect: "slide",
            draggable: false,
            droppable: false,
            resizable: false,
            duration: 200,
            //isExpanded: true,
            expanded: null,
            collapsed: null
        },
        _create: function () {
            var el = this.element, self = this, eventPrefix = this.widgetEventPrefix;
            if (!el.hasClass("d-panel")) el.addClass("d-panel");
            self.header = $(">.d-panel-header", el);
            self.body = $(">.d-panel-body", el);
            if (this.options.collapsed)
                el.bind(eventPrefix + "collapsed", this.options.collapsed);
            if (this.options.expanded)
                el.bind(eventPrefix + "expanded", this.options.expanded);

            if (el.hasClass("d-panel-collapsed")) { self.body.hide(); }

            self.header.click(function () {
                if (el.data("isdrag")) { el.data("isdrag", false); return; }
                if (el.hasClass("d-panel-collapsed"))
                    self.expand();
                else
                    self.collapse();
            });

            self.setResize();

            if (self.options.draggable) {
                el.draggable({
                    handle: self.header,
                    iframeFix: true,
                    stop: function () { el.data("isdrag", true); }
                });
            }
        },
        _fx: function () {
            return {};
        },
        setResize: function () {
            if (this.options.resizable) {
                //                if (this.body.hasClass("ui-resizable"))
                //                    this.body.removeClass("ui-resizable");
                this.body.resizable({
                    alsoResize: this.element,
                    helper: "ui-state-highlight"
                });
            }
        },
        _triggerEvent: function (eventName, eventArgs) {
            this.element.trigger(this.widgetEventPrefix + eventName, eventArgs);
        },
        expand: function () {
            var $h = this.header, $b = this.body, self = this;
            if (this.element.hasClass("d-panel-collapsed")) {
                $b.show(this.options.showEffect, self._fx(), this.options.duration, function () {
                    self.element.removeClass("d-panel-collapsed");
                    self._triggerEvent("expanded", { "header": $h, "body": $b });
                });
            }
        },
        collapse: function () {
            var $h = this.header, $b = this.body, self = this;
            if (this.element.hasClass("d-panel-collapsed")) return;
            this.element.css("height", "auto");
            $b.hide(this.options.hideEffect, self._fx(), this.options.duration, function () {
                self.element.addClass("d-panel-collapsed");
                self._triggerEvent("collapsed", { "header": $h, "body": $b });
            });
        },
        destroy: function () {
            $.Widget.prototype.destroy.call(this);
        }
    });
    $.widget("ui.tooltip", {
        options: {
            actived: null,
            pos: "right top",
            showEffect: "blind",
            hideEffect: "blind",
            duration: 100,
            opacity: 0.8
        },
        _create: function () {
            var self = this, eventPrefix = this.widgetEventPrefix, el = this.element
            targetElements = $("[title]", el);
            if (this.options.actived)
                el.bind(eventPrefix + "actived", this.options.actived);

            if (targetElements.length) {
                targetElements.each(function (i, n) {
                    var $t = $(n);
                    if ($t.attr("title")) {
                        $t.mouseover(self._delegate(self, self._onmouseenter))
                           .mouseout(self._delegate(self, self._onmouseleave))
                           .data("title", $t.attr("title"))
                           .removeAttr("title");
                    }
                });
            }
        },
        _delegate: function (context, handler) {
            return function (e) {
                handler.apply(context, [e, this]);
            };
        },
        _triggerEvent: function (eventName, eventArgs) {
            this.element.trigger(this.widgetEventPrefix + eventName, eventArgs);
        },
        _contains: function (parent, child) {
            try {
                return $.contains(parent, child);
            } catch (e) {
                return false;
            }
        },
        _onmouseenter: function (e, element) {
            if (element.holder) {
                if (element.holder.hasClass("d-tooltip-actived")) return;
            }
            this.active(e, element);
        },
        _onmouseleave: function (e, element) {
            if (element.holder) {
                if (element.holder.hasClass("d-tooltip-actived"))
                    this.deactive(e, element);
            }
        },
        active: function (e, element) {
            var self = this, $el = $(element);
            if (element.holder == undefined)
                element.holder = $("<div/>").addClass("d-tooltip")
                                                .html($el.data("title"))
                                                .position({
                                                    my: "left top",
                                                    at: self.options.pos,
                                                    of: element,
                                                    offset: "5 0",
                                                    collision: "flip"
                                                }).appendTo("body");
            clearTimeout($el.data("tipTimer"));

            $el.data("tipTimer", setTimeout(function () {
                self._triggerEvent("actived", { "element": element, "tip": element.holder });
                element.holder.css({
                    "overflow": "auto",
                    "opacity": self.options.opacity
                })
                                .addClass("d-tooltip-actived")
                                .show(self.options.showEffect, {}, self.options.duration);
            }), 100);

            //.stop()
            //.animate(self.options.showfx, self.options.duration);
        },
        deactive: function (e, element) {
            var self = this, $el = $(element);
            if (element.holder) {
                clearTimeout($el.data("tipTimer"));
                $el.data("tipTimer", setTimeout(function () {
                    element.holder.removeClass("d-tooltip-actived")
                .hide(self.options.showEffect, {}, self.options.duration);
                    //.stop().animate(self.options.hidefx, self.options.duration);
                    //.fadeOut("fast");
                }, 100));
            }
        },
        destroy: function () {
            $.Widget.prototype.destroy.call(this);
        }
    });
    $.widget("ui.dtree", {
        options: {
            nodeTemplate: "<li><img src='#{url}' class='d-treenode-img' /><span class='d-treenode-text'>#{label}</span></li>",
            enableDropAndDrag: false,
            singlePathExpand: false,
            checkboxes: false,
            showTreeLines: true,
            dragstart: null,
            dropTargets: null,
            drag: null,
            dragstop: null,
            dropped: null,
            dropover: null,
            dropout: null,
            selected: null,
            selectedNode: null,
            checked: null,
            collapsed: null,
            expanded: null,
            nodeClass: null,
            selectedClass: null,
            hoverClass: null,
            disableClass: null,
            beforeNodeLoad: null,
            nodeLoadError: null,
            nodeLoaded: null,
            popupNodes: null,
            duration: 300,
            showEffect: "blind",
            hideEffect: "blind"
        },
        _create: function () {
            this.element.addClass("d-tree");
            this._initNodes($("li:not(.d-menu-item,.d-combo-item)", this.element));
            this._bindingEvents();
        },
        _bindingEvents: function () {
            var eventPrefix = this.widgetEventPrefix;
            if (this.options.selected)
                this.element.bind(eventPrefix + "selected", this.options.selected);

            if (this.options.drag)
                this.element.bind(eventPrefix + "drag", this.options.drag);

            if (this.options.dragstop)
                this.element.bind(eventPrefix + "dragstop", this.options.dragstop);

            if (this.options.dragstart)
                this.element.bind(eventPrefix + "dragstart", this.options.dragstart);

            if (this.options.dropout)
                this.element.bind(eventPrefix + "dropout", this.options.dropout);

            if (this.options.dropover)
                this.element.bind(eventPrefix + "dropover", this.options.dropover);

            if (this.options.dropped)
                this.element.bind(eventPrefix + "dropped", this.options.dropped);

            if (this.options.collapsed)
                this.element.bind(eventPrefix + "collapsed", this.options.collapsed);

            if (this.options.expanded)
                this.element.bind(eventPrefix + "expanded", this.options.expanded);

            if (this.options.checked)
                this.element.bind(eventPrefix + "checked", this.options.checked);

            if (this.options.beforeNodeLoad)
                this.element.bind(eventPrefix + "beforeNodeLoad", this.options.beforeNodeLoad);

            if (this.options.nodeLoadError)
                this.element.bind(eventPrefix + "nodeLoadError", this.options.nodeLoadError);

            if (this.options.nodeLoaded)
                this.element.bind(eventPrefix + "nodeLoaded", this.options.nodeLoaded);

            if (this.options.popupNodes)
                this.element.bind(eventPrefix + "popupNodes", this.options.popupNodes);

            //            if (this.options.selectedKey)
            //                this.selectNodeByKey(this.options.selectedKey);
        },
        _triggerEvent: function (eventName, eventArgs) {
            this.element.trigger(this.widgetEventPrefix + eventName, eventArgs);
        },
        select: function ($li) {
            var opts = this.options,
            $target = $li,
            selectedNodes = $(".d-treenode-selected", this.element);

            if ($li == null)
                $target = this.element.children(".d-treenode").first();

            if ($target.length) {
                if (selectedNodes.length) {
                    selectedNodes.removeClass("d-treenode-selected");
                    if (opts.selectedClass)
                        selectedNodes.removeClass(opts.selectedClass);
                }

                $target.addClass("d-treenode-selected");
                if (opts.selectedClass) $li.addClass(opts.selectedClass);

                opts.selectedNode = $target;
                this._triggerEvent("selected", $target);
            }
        },
        _setOption: function (key, value) {
            if (key == "selectedNode") {
                if (value)
                    this.select(value);
            }
            else {
                this.options[key] = value;
            }
            return this;
        },
        _initNodes: function (_nodes) {
            var self = this, opts = self.options;
            if (_nodes) {
                if (_nodes.length) {
                    _nodes.each(function (i, n) {
                        var $li = $(n);
                        $li.addClass("d-treenode")
                           .wrapInner("<div class='d-treenode-content'></div>");

                        if (opts.nodeClass) $li.addClass(opts.nodeClass);

                        var _child = $li.children(".d-treenode-content").children("ul");
                        if (_child.length) {
                            $li.addClass("d-treenode-parent");
                            if (!_child.hasClass("d-treenodes-holder"))
                                _child.addClass("d-treenodes-holder");
                            _child.appendTo($li);
                        }
                        self._createNodeButton($li);
                        $li.children(".d-treenode-content")
                        //.disableSelection()
                           .click(function (event) {
                               event.stopPropagation();
                               if (!$li.hasClass("d-treenode-disabled"))
                                   self.select($li);
                           })
                           .dblclick(function (event) {
                               self._toggle($li);
                           })
                           .hover(function (event) {
                               if (!$li.hasClass("d-treenode-disabled")) {
                                   $li.addClass("d-treenode-hover");
                                   if (opts.hoverClass) $li.addClass(opts.hoverClass);
                               }
                           },
                            function (event) {
                                if (!$li.hasClass("d-treenode-disabled")) {
                                    $li.removeClass("d-treenode-hover");
                                    if (opts.hoverClass) $li.removeClass(opts.hoverClass);
                                }
                            });

                        if (self.options.checkboxes)
                            self._enableCheckaboxs($li);

                        if (self.options.enableDropAndDrag)
                            self._enableDropAndDrag(n);
                    });
                }
            }
        },
        _enableCheckaboxs: function ($li) {
            var self = this, cbox = $("<input type='checkbox'>").addClass("d-treenode-checkbox").prependTo($li.children(".d-treenode-content"));
            cbox.click(function () {
                var cbs = $li.find(".d-treenode-checkbox");
                if (cbs.length > 0)
                    cbs.attr("checked", cbox.attr("checked"));
                var _parent = $li.parents(".d-treenode");
                if (_parent.length) {
                    var _vals = 0;
                    $li.siblings().each(function (i, n) {
                        if ($(n).children(".d-treenode-content").children(".d-treenode-checkbox").attr("checked") == cbox.attr("checked"))
                            _vals++;
                    });

                    if (_vals == $li.siblings().length)
                        _parent.children(".d-treenode-content").children(".d-treenode-checkbox").attr("checked", cbox.attr("checked"));
                    self._triggerEvent("checked", { node: $li, checked: cbox.attr("checked") });
                }
            });
        },
        _enableDropAndDrag: function (_node) {

            var self = this, opts = this.options;

            $(_node).children(".d-treenode-content").draggable({
                revert: 'invalid',
                greedy: false,
                iframeFix: true,
                helper: 'clone',
                opacity: 0.8,
                start: function (event, ui) {
                    self._triggerEvent("dragstart", $(this).closest(".d-treenode"));
                },
                stop: function (event, ui) {
                    self._triggerEvent("dragstop", $(this).closest(".d-treenode"));
                },
                drag: function (event, ui) {
                    self._triggerEvent("drag", $(this).closest(".d-treenode"));
                }
            });

            if (opts.dropTargets) {
                var _targets = $(opts.dropTargets);
                if (_targets.length) {
                    _targets.droppable({
                        accept: ".d-treenode-content",
                        over: function (event, ui) {
                            self._triggerEvent("dropout", { node: ui.draggable, container: $(this) });
                        },
                        out: function (event, ui) {
                            self._triggerEvent("dropover", { node: ui.draggable, container: $(this) });
                        },
                        drop: function (event, ui) {
                            self._triggerEvent("dropped", { node: ui.draggable, container: $(this) });
                        }
                    });
                }
            }
            //drop to it node
            $(_node).droppable({
                accept: ".d-treenode-content",
                greedy: true,
                out: function (event, ui) {
                    self._triggerEvent("dropout", { node: ui.draggable, targetNode: $(this).closest(".d-treenode") });
                },
                over: function (event, ui) {
                    self._triggerEvent("dropover", { node: ui.draggable, targetNode: $(this).closest(".d-treenode") });
                },
                drop: function (event, ui) {
                    var _srcNode = ui.draggable.closest(".d-treenode"),
                    _srcParent = _srcNode.closest(".d-treenode-parent"),
                     thisNode = $(this).closest(".d-treenode");

                    if (_node == _srcNode[0]) return false; //drop on self

                    if (_srcNode.has(thisNode).length) return false;

                    var _holder = $(">.d-treenodes-holder", this);

                    if (_holder.length == 0) {
                        _holder = $("<ul/>").addClass("d-treenodes-holder");
                        $(this).append(_holder);
                        thisNode.addClass("d-treenode-parent");
                    }
                    _holder.append(_srcNode);

                    if (_srcParent.length) {
                        if (_srcParent.find(".d-treenode").length == 0) {
                            _srcParent.removeClass("d-treenode-parent")
                                       .children(".d-treenodes-holder").remove();
                        }
                    }

                    var _pos = 0;
                    var _children = $(this).find(".d-treeview-node");
                    if (_children.length)
                        _pos = _children.index(_srcNode);
                    self._triggerEvent("dropped", { node: _srcNode, targetNode: thisNode, position: _pos });
                }
            });
        },
        collape: function ($li) {
            if ($li.hasClass("d-treenode-collapsed")) return;

            $li.removeClass("d-treenode-expanded")

            if ($li.hasClass("d-treenode-parent")) {
                $li.find(".d-treenodes-holder:first").hide(this.options.hideEffect, {}, this.options.duration, function () { $li.addClass("d-treenode-collapsed") });
                this._triggerEvent("collapsed", $li);
            }
        },
        expand: function ($li) {
            var self = this;
            if ($li.hasClass("d-treenode-expanded")) return;

            $li.removeClass("d-treenode-collapsed");
            if ($li.hasClass("d-treenode-parent")) {
                $li.find(".d-treenodes-holder:first").show(this.options.showEffect, {}, this.options.duration, function () { $li.addClass("d-treenode-expanded"); });
                if (this.options.singlePathExpand) {
                    var _siblings = $li.siblings().not(".d-treenode-disabled");
                    if (_siblings.length) _siblings.each(function (i, n) {
                        self.collape($(n));
                    });
                }
                this._triggerEvent("expanded", $li);
            }
        },
        _toggle: function ($li) {
            if ($li.hasClass("d-treenode-collapsed")) {
                this.expand($li);
            }
            else {
                if ($li.hasClass("d-treenode-hasChildren")) {
                    this._triggerEvent("popupNodes", $li);
                    //this._trigger("popupNodes", $li);
                    //this._triggerEvent("popupNodes", $li);
                }
                else
                    this.collape($li);
            }
        },
        _createNodeButton: function ($li) {
            var self = this,
            _tbtn = $("<div/>").addClass("d-treenode-button")
                                         .prependTo($li);
            _tbtn.click(function (event) {
                event.stopPropagation();
                if ($li.hasClass("d-treenode-parent") || $li.hasClass("d-treenode-hasChildren"))
                    self._toggle($li);
            });
        },
        loadNodes: function (_url, _httpMethod, _routeData, _parent) {
            var self = this;
            $.ajax({
                type: _httpMethod,
                url: _url,
                dataType: "json",
                data: _routeData,
                beforeSend: function () {
                    // Trigger beforeNodeLoad
                    self._triggerEvent("beforeNodeLoad", _parent);
                },
                error: function (request, textStatus, errorThrown) {
                    //trigger nodeLoadError event
                    self._triggerEvent("nodeLoadError", { node: _parent, exception: { rquest: request, status: textStatus, error: errorThrown} });
                },
                success: function (data) {
                    // trigger nodeLoaded event
                    if ((self.options.nodeTemplate) && (data)) {
                        var $parent = _parent ? $(_parent) : self.element;
                        if ($parent[0].tagName == "LI") {
                            $parent.addClass("d-treenode-parent")
                            //.addClass("d-treenode-collapsed")
                                        .removeClass("d-treenode-hasChildren");
                            $parent = $("<ul/>").addClass("d-treenodes-holder")
                                                            .appendTo(_parent);

                        }
                        $("#" + self.options.nodeTemplate).tmpl(data).appendTo($parent);
                        self._initNodes($("li", $parent));
                        if (_parent)
                            self.expand(_parent);
                        self._triggerEvent("nodeLoaded", _parent);
                    }
                }
            });
        },
        findNodeElement: function (key, value) {
            return this.element.find("li[" + key + "=" + value + "]");
        },
        findNodeElementByKey: function (value) {
            return this.findNodeElement("key", value);
        },
        getCheckedNodes: function () {
            if (this.options.checkboxes) {
                var _checkedboxs = this.element.find(".d-treenode-checkbox");
                if (_checkedboxs.length) {
                    var nodeArgs = new Array();
                    _checkedboxs.each(function (i, n) {
                        if ($(n).attr("checked")) {
                            nodeArgs.push($(n).parent().closest(".d-treenode"));
                        }
                    });
                    return nodeArgs;
                }
            }
            return null;
        },
        addRoot: function (node) {
            this.element.append($(node));
            this._initNodes($(node));
        },
        addNode: function (node) {
            if (this.options.selectedNode) {
                var _holder = $(this.options.selectedNode).children(".d-treenodes-holder");
                if (_holder.length == 0)
                    _holder = $("<ul/>").addClass("d-treenodes-holder").appendTo($(this.options.selectedNode));

                _holder.append($(node));
                this._initNodes($(node));
            } else this.addRoot(node);
        },
        addNodes: function (nodes) {
            if (nodes) {
                if (nodes.length) {
                    var _ns = $(nodes);
                    if (_ns.get(0).tagName == "UL") {
                        _ns = $(nodes).children();
                        this.element.append(_ns);
                        this._initNodes(_ns);
                        this._initNodeHolder(_ns);
                        this.element.find("li").dtree("refresh");
                    }
                }
            }
        },
        destroy: function () {
            $.Widget.prototype.destroy.call(this);
        }
    });
    $.widget("ui.watermark", {
        options: {
            waterMark: null,
            waterMarkClass: ""
        },
        _create: function () {
            var self = this, opts = this.options, el = this.element;

            self._setWaterMark();

            el.bind("focus", function () {
                self._removeWaterMark();
            });

            el.bind("blur", function () {
                self._setWaterMark();
            });

            var _form = el.closest("form");
            if (_form.length) {
                _form.submit(function () {
                    self._removeWaterMark();
                });
            }
        },
        _setWaterMark: function () {
            var opts = this.options, el = this.element;
            if (opts.waterMark) {
                if (el.val() == "") {
                    if (opts.waterMarkClass)
                        el.addClass(opts.waterMarkClass);
                    el.val(opts.waterMark);
                }
            }
        },
        _removeWaterMark: function () {
            var opts = this.options, el = this.element;
            if (opts.waterMark) {
                if (el.val() == opts.waterMark) {
                    if (opts.waterMarkClass)
                        el.removeClass(opts.waterMarkClass);
                    el.val("");
                }
            }
        },
        destroy: function () {
            this.element.unbind();
            $.Widget.prototype.destroy.call(this);
        }
    });
})(jQuery);